home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / dbase / do1beta.zip / DO.DOC < prev    next >
Text File  |  1991-08-23  |  165KB  |  4,621 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.  
  11.  
  12.  
  13.  
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.                         dObject Version 1.0 User Guide
  31.               Object-Oriented Programming Language for DBASE(tm)
  32.                 Copyright (c) 1991 Intelligent Systems Research
  33.                               All Rights Reserved
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  63.  
  64.  
  65.                               1.0 Introduction
  66.  
  67.      1.1 Introduction
  68.  
  69.      Welcome to  Object-Oriented programming for DBASE(tm) !  dObject is an
  70.      object-oriented programming language with built-in  base  classes  for
  71.      handling DBASE  data,  memo,  and index files.  Using dObject, you can
  72.      build complex applications that use your existing DBASE  files  and  a
  73.      class library  of  over  15  classes  and 300 methods.  You can define
  74.      your own classes and methods that inherit the  features  of  the  base
  75.      classes.   You  can  create new DBASE data, memo, and index files, and
  76.      you can write graphics and full-color windowed hypertext  applications
  77.      that display your DBASE data.
  78.  
  79.  
  80.      dObject includes the following features:
  81.  
  82.           *   a  fast,  efficient  interpreted  language  for  writing
  83.           object-oriented DBASE applications
  84.  
  85.           * a built-in full screen  text  editor  callable  from  your
  86.           applications with hypertext on-line help
  87.  
  88.           *   over   300   built-in   methods  for  integer  and  real
  89.           arithmetic, characters, strings, and dates
  90.  
  91.           * a text-mode windowing system
  92.  
  93.           * a graphics system based on the Borland BGI
  94.  
  95.           * a pop-up menu facility
  96.  
  97.           * DBASE-like SAY and GET output to windows, and code  for  a
  98.           full screen DBASE field editor
  99.  
  100.           * output logging to printers and DOS text files
  101.  
  102.           * LAN-compatible row and file locking of DBASE files
  103.  
  104.           *   a  powerful  GREP-like  pattern  matching  function  for
  105.           strings and DBASE character fields
  106.  
  107.           * a hypertext facility linked to DBASE
  108.  
  109.           * multi-dimensional arrays
  110.  
  111.           * an advanced Collection class  for  managing  complex  data
  112.           structures
  113.  
  114.           *  a  C-style  preprocesssor  for  constant  definitions and
  115.           program text inclusions
  116.  
  117.  
  118.  
  119.                                      - 2 -
  120.  
  121.  
  122.                                                        Chapter 1: Introduction
  123.  
  124.  
  125.      dObject provides the following advantages over the  DBASE  programming
  126.      language:
  127.  
  128.           *  facilities  for defining classes and methods that are far
  129.           superior to the UDF facility  in  DBASE,  including  support
  130.           for inheritance and polymorphism
  131.  
  132.           *  advanced  date  handling including international formats,
  133.           julian dates, and date arithmetic
  134.  
  135.           * facilities for  providing  sophisticated  user  interfaces
  136.           for  DBASE(tm)  applications,  including  use  of  multiple,
  137.           overlapping full-color windows and pop-up menus
  138.  
  139.           * facilities for building hypertext  applications  that  use
  140.           DBASE data and index files
  141.  
  142.           * graphics
  143.  
  144.      1.2 Manual Overview
  145.  
  146.      This  manual  is  both  a user guide and a reference guide to dObject.
  147.      The chapters include:
  148.  
  149.  
  150.           * Chapter 1 - Introduction
  151.  
  152.           * Chapter 2 - Getting Started
  153.  
  154.           * Chapter 3 - dObject Statements
  155.  
  156.           * Chapter 4 - dObject Classes
  157.  
  158.           * Chapter 5 - Numeric Classes
  159.  
  160.           * Chapter 6 - Logical Operations
  161.  
  162.           * Chapter 7 - Characters and Strings
  163.  
  164.           * Chapter 8 - Dates
  165.  
  166.           * Chapter 9 - Windows and Menus
  167.  
  168.           * Chapter 10 - Arrays and Collections
  169.  
  170.           * Chapter 11 - Files and Devices
  171.  
  172.           * Chapter 12 - DBASE File Programming
  173.  
  174.           * Chapter 13 - BGI Graphics
  175.  
  176.  
  177.  
  178.  
  179.                                      - 3 -
  180.  
  181.  
  182. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  183.  
  184.  
  185.      1.3 How to Contact ISR
  186.  
  187.      If you need technical support or would  like  to  contact  Intelligent
  188.      Systems  Research  with  comments,  suggestions,  or  questions  about
  189.      dObject, please write to us at:
  190.  
  191.  
  192.              Intelligent Systems Research
  193.              P.O. Box 3690
  194.              Chicago IL 60654 USA
  195.              (312)-878-6054
  196.  
  197.              CompuServ: Send E-mail to userid 70304,2520
  198.  
  199.  
  200.      Please include your dObject version number,  your  computer  make  and
  201.      model  number,  and your operating system make and model number if you
  202.      have technical questions or need detailed technical support.
  203.  
  204.  
  205.  
  206.                            2.0 Getting Started
  207.  
  208.      2.1 Hardware Requirements
  209.  
  210.      dObject requires the following minimal hardware configuration:
  211.  
  212.  
  213.           * an 80286, 80386 or 80406 CPU
  214.  
  215.           * 640KB main memory
  216.  
  217.           * a hard disk drive
  218.  
  219.           * MS-DOS 3.0 or above
  220.  
  221.      2.2 Installing dObject
  222.  
  223.      The shareware version of dObject does not need to be installed  beyond
  224.      the "unzip"  of  the  distribution  .ZIP  file.    The  files  DO.EXE,
  225.      HELP.DBF, HELP.DBT, HELP.NDX, ERROR.DBF, ERROR.NDX, and DO.CFG  should
  226.      reside in the hard disk directory "DOBJECT".
  227.  
  228.      The  registered  version  of  dObject comes with an INSTALL program on
  229.      the distribution diskette.  The INSTALL program will  prompt  you  for
  230.      the  name  of  a  directory to create on your hard disk, and then copy
  231.      the dObject distribution files to that directory.  If  you  wish,  you
  232.      can duplicate this yourself by issuing the DOS commands below:
  233.  
  234.  
  235.  
  236.              C:\>md dobject
  237.  
  238.  
  239.                                      - 4 -
  240.  
  241.  
  242.                                                  Chapter 2: Getting Started
  243.  
  244.  
  245.              C:\>cd dobject
  246.              C:\DOBJECT>copy a:do.exe
  247.              C:\DOBJECT>copy a:do.cfg
  248.              C:\DOBJECT>copy a:*.dbf
  249.              C:\DOBJECT>copy a:*.dbt
  250.              C:\DOBJECT>copy a:*.ndx
  251.              C:\DOBJECT>copy a:*.do
  252.              C:\DOBJECT>copy a:*.bgi
  253.              C:\DOBJECT>copy a:*.chr
  254.  
  255.  
  256.      You  should  also  specify  the  DOBJECT  directory as one of the PATH
  257.      options in your DOS AUTOEXEC.BAT file.  dObject will  always  look  in
  258.      the  directory  that  the  DO.EXE  file  is  in for the HELP and ERROR
  259.      databases (including memo and index files).  Make sure that  when  you
  260.      install  dObject,  all  these  files  are in the same directory as the
  261.      executable  file  DO.EXE,  otherwise  the  on-line  help   and   error
  262.      reporting systems will not work properly.
  263.  
  264.  
  265.      Because  dObject  provides  direct access to existing DBASE III format
  266.      files, and becuase  dObject  uses  several  DBASE  III  files  in  its
  267.      runtime  environment,  you should set the DOS FILES and BUFFERS option
  268.      in your config.sys file to at least the following values:
  269.  
  270.  
  271.              FILES=20
  272.              BUFFERS=20
  273.  
  274.  
  275.      To run the BGI demonstration program (BGIDEMO.DO) you must also  first
  276.      define a  DOS  environment variable named BGIPATH.  This variable must
  277.      contain the name of the directory where the supplied BGI  drivers  and
  278.      font files  are  stored.    If  you  install  dObject in the directory
  279.      C:\DOBJECT, you should add this line to your autoexec.bat file:
  280.  
  281.              SET BGIPATH=C:\DOBJECT
  282.  
  283.  
  284.      2.3 Running dObject
  285.  
  286.      To run dObject, at the DOS prompt type "do":
  287.  
  288.  
  289.              C:\>do
  290.  
  291.              dObject Version 1.0 (Shareware)
  292.              Copyright (c) 1991 Intelligent Systems Research
  293.              Please register this version for support and updates
  294.              Press any key to continue...
  295.  
  296.  
  297.  
  298.  
  299.                                      - 5 -
  300.  
  301.  
  302. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  303.  
  304.  
  305.      Pressing any key at  this  point  will  cause  dObject  to  issue  the
  306.      "dObject> "  prompt  and  accept commands.  (The registered version of
  307.      dObject goes directly to  the  "dObject>  "  prompt  without  pausing;
  308.      this is  a  small  reminder  to register the shareware version !).  To
  309.      run a dObject source program directly from the DOS prompt,  type  "do"
  310.      followed  by  the name of the file to run, with a default extension of
  311.      "DO".  For example, to run the dObject program in the  file  "demo.do"
  312.      in the current DOS directory, issue the command:
  313.  
  314.              C:\> do demo
  315.  
  316.  
  317.  
  318.                            3.0 dObject Statements
  319.  
  320.      3.1 Statements
  321.  
  322.      dObject  accepts  statements  at the "dObject>" prompt using free-form
  323.      input.  Statements can be entered in any number of lines but  must  be
  324.      terminated with  a  semicolon.    dObject  will  prompt  for statement
  325.      continuation with the "more>" prompt until  a  semicolon  is  entered.
  326.      dObject accepts the following legal statements:
  327.  
  328.      STATEMENT                       DESCRIPTION
  329.  
  330.      help;                           enter online hypertext help system and
  331.                                      display table of contents
  332.      cls;                            clear screen (current window)
  333.      exit;                           exit dObject and return to DOS (also
  334.                                      recognizes "quit;")
  335.      edit <filename>;                edit file (default extension .DO)  ESC
  336.                                      - exit without saving changes;  F10 -
  337.                                      exit and save changes
  338.      for(statement;exp;statement)    execute statements for range of values
  339.      <statements>
  340.      while <exp> <statements>        while expression is true execute
  341.                                      statements
  342.      if  <exp> <statements> else     conditional execution of statements
  343.      <statements>                    with else clause
  344.      if <exp> <statements>           conditional execution of statements
  345.      do <filename>;                  execute statements in file  (default
  346.                                      extension .DO)
  347.      dos;                            suspend dObject and shell to DOS
  348.      return(<exp>);                  return expression as method result
  349.      show <item>;                    shows internal information about
  350.                                      dObject. "show classes"  shows defined
  351.                                      classes, "show methods" shows defined
  352.                                      methods, "show set" shows SET
  353.                                      variables, "show variables" shows all
  354.                                      defined user  variables
  355.      switch (exp) {<cases>}          conditional execution of cases
  356.      ? <exp>[,<exp>...];             print expression values in current
  357.  
  358.  
  359.                                      - 6 -
  360.  
  361.  
  362.                                                  Chapter 3: dObject Statements
  363.  
  364.  
  365.                                      window
  366.      <exp>;                          evaluate the expression
  367.  
  368.      dObject  accepts comments within source programs using the conventions
  369.      of the "C"  programming  language.    Comments  must  begin  with  the
  370.      characters "/*"  and  end with the characters "*/".  All characters in
  371.      between, including spaces, tabs, and newlines, are treated as  comment
  372.      characters and  are ignored by the interpreter.  The following example
  373.      demonstrates legal dObject comments:
  374.  
  375.  
  376.      /*
  377.              this is a comment
  378.      */
  379.      method Int::zero(self)             /* comments are allowed anywhere */
  380.      {
  381.              return(0); % this is an end-of-line comment
  382.      }
  383.  
  384.  
  385.      To exit from dObject and return to the DOS prompt,  issue  the  "exit"
  386.      command:
  387.  
  388.  
  389.              dObject> exit;
  390.  
  391.  
  392.      To review the on-line hypertext help, issue the "help" command:
  393.  
  394.  
  395.              dObject> help;
  396.  
  397.  
  398.  
  399.      dObject  provides  a way to execute other dObject program source files
  400.      through the use of the  "do"  command  with  a  filename  to  execute.
  401.      dObject  will supply a default extension of ".do" if you do not supply
  402.      one.  For example, to execute the statements in  the  file  "test.do",
  403.      issue the statement:
  404.  
  405.              dObject> do test;
  406.  
  407.  
  408.      3.2 Errors
  409.  
  410.      If  you  make an error in a dObject statement, dObject will attempt to
  411.      locate the  error  and  print  out  the  offending  statement  with  a
  412.      relevant error  message.   The error display will be shown in an Error
  413.      window displayed in  the  lower  left  corner  of  the  screen.    The
  414.      complete  list of error codes generated by dObject is contained in the
  415.      supplied file ERROR.DBF.
  416.  
  417.  
  418.  
  419.                                      - 7 -
  420.  
  421.  
  422. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  423.  
  424.  
  425.      To  produce  the  error   displauy,   dObject   calls   the   built-in
  426.      Int::onError()  method  and passes it the Int error code of the error.
  427.      You can re-define this method in your applications to change  the  way
  428.      that error messages are displayed:
  429.  
  430.  
  431.      /*
  432.              demonstration of the Int::onError() method
  433.              this method is called whenever dObject detects a parse or runtime
  434.              error in a program; normally dObject creates a 1-line window
  435.              at the bottom of the display screen and prints out the error
  436.              number, an error message, and the statement where the error
  437.              was detected.  you can re-define this method to handle errors
  438.              for your own applications
  439.      */
  440.      method Int::onError(self)
  441.      {
  442.              w = new(Window,1,112,112," Error ",10,10,5,50);
  443.              db = new(Dbffile,"error");
  444.              ndx = new(Ndxfile,db,"error");
  445.              seek(db,self);
  446.              ? "ERROR ",self,": ",msg;
  447.              readchar();
  448.              remove(w);
  449.      }
  450.  
  451.      /*
  452.              cause an error
  453.      */
  454.      exit(10002);
  455.  
  456.  
  457.      3.3 Breaks
  458.  
  459.      To  interrupt  a  dObject  program during execution, press the Control
  460.      key and the Break key at the same time (Ctrl-Break).  This will  cause
  461.      dObject  to  issue  an error message for the break, and then return to
  462.      the dObject> prompt.
  463.  
  464.  
  465.  
  466.      3.4 Preprocessor
  467.  
  468.      dObject includes a built-in  preprocessor  for  defining  compile-time
  469.      constants and  file includes.  dObject accepts constant definitions of
  470.      the form:
  471.  
  472.              #define NAME VALUE
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.                                      - 8 -
  480.  
  481.  
  482.                                                  Chapter 3: dObject Statements
  483.  
  484.  
  485.      where NAME is the name of the constant to define,  and  VALUE  is  the
  486.      value to  assign  to  it.   Values can be any single token of text, or
  487.      any string of text delimited with double quotes.    For  example,  the
  488.      following are all legal dObject constant definitions:
  489.  
  490.  
  491.              /*
  492.                      define some commonly used integer codes for characters
  493.              */
  494.              #define ESC 27
  495.              #define CR 13
  496.              #define TRUE "T"
  497.              /*
  498.                      define an alias name for a dObject function
  499.              */
  500.              #define CURRENT_DATE "date()"
  501.  
  502.  
  503.      Whenever  dObject  encounters  a defined constant anywhere in the text
  504.      of a program, it will substitute the defined text before  parsing  and
  505.      executing the  statement.    Use of this technique makes your programs
  506.      more readable and understandable.  For  example,  the  following  code
  507.      uses the constants defined above:
  508.  
  509.              /*
  510.                      read a character from the keyboard
  511.              */
  512.              c = inkey();
  513.              if(c == ESC) ? "the escape key was pressed";
  514.              if(c == CR) ? "the return key was pressed";
  515.  
  516.  
  517.      A  file  can  be  included  in  the source text before it is parsed by
  518.      using the "include" directive:
  519.  
  520.              #include "keydef.do"
  521.  
  522.  
  523.      3.5 Variables
  524.  
  525.      In dObject, variables are used to store any kind of  value  in  memory
  526.      for use  by  your  program.    The names of these variables must begin
  527.      with a lower case alphabetic character (since  upper  case  names  are
  528.      reserved for  class  names);    and  can  then  contain  any number of
  529.      alphabetic or numeric characters, as well  as  the  underscore.    The
  530.      variable  name  must  not  be  one  of  the following dObject reserved
  531.      keywords:  while, for, if, then, else, do, return or method.
  532.  
  533.      For example, the following are legal dObject variable names:
  534.  
  535.           * a
  536.  
  537.  
  538.  
  539.                                      - 9 -
  540.  
  541.  
  542. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  543.  
  544.  
  545.           * a1
  546.  
  547.           * my_variable
  548.  
  549.      The following are NOT legal variable names:
  550.  
  551.           * 1a (begins with a numeric character)
  552.  
  553.           * My_variable (begins with an uppercase character)
  554.  
  555.           * my-variable (uses the '-' character)
  556.  
  557.           * while (uses the reserved dObject keyword while)
  558.  
  559.      Variables use memory space within dObject that can  be  re-used  later
  560.      if your  program no longer needs the variable.  To reclaim the storage
  561.      space for a variable, send the "release"  message  to  an  Exp  object
  562.      containing the name of the variable:
  563.  
  564.              dObject> a = 32;
  565.              dObject> release(#a);
  566.  
  567.  
  568.      3.6 Literals
  569.  
  570.      Literal   values  are  sequences  of  numbers,  letters,  and  special
  571.      characters that are interpreted  as  actual  values  by  dObject,  not
  572.      variable  names.  dObject  accepts  literal  values  in  the following
  573.      formats (note that hex integer constants are defined using  a  leading
  574.      dollar sign):
  575.  
  576.  
  577.      CLASS          FORMAT         EXAMPLE
  578.  
  579.      Nil:           nil            nil
  580.      Date:          mm/dd/yyyy     5/10/1990
  581.      Char:          'c'            'a'
  582.      String:        "ccc"          "this is a string"
  583.      Int (decimal): n              123
  584.      Int (hex):     $n             $1ff
  585.      Long:          nL             123L
  586.      Real:          n.d            12.34
  587.      Logical:       T or F         T
  588.      Collection:    [v1,v2,v3...]  [1,2,$1ff,T,3.3,"four",'5',(1,"one"),5/10/90]
  589.      Exp:           #exp           #date()
  590.  
  591.      3.7 Expressions
  592.  
  593.      Expressions  in  dObject  are combinations of literal values, variable
  594.      names, and "messages". Messages are sent to objects in dObject  either
  595.      as  operators  or  as named messages. Operators are special characters
  596.      (usually one or two characters)  that  have  a  special  meaning  when
  597.  
  598.  
  599.                                      - 10 -
  600.  
  601.  
  602.                                                  Chapter 3: dObject Statements
  603.  
  604.  
  605.      applied  to  values,  and  are  generally used in messages of the form
  606.      "object operator object".  For example, in dObject the expression 1  +
  607.      2 means send the "plus" message to Int 1 with an argument of Int 2.
  608.  
  609.  
  610.      Named  messages are always of the form name(object,args), where "name"
  611.      is the name of the message to send, "object" is  the  object  to  send
  612.      the  message to, and "args" is zero or more values to use as arguments
  613.      to the message.  For example, the  expression  "clear(w)"  in  dObject
  614.      means  send  the  "clear" message to the object stored in the variable
  615.      "w" (presumably a Window object) with no argument. The only  exception
  616.      to  this  convention  are  messages  sent  to  the  Nil  object, which
  617.      effectively have no object or arguments in the calling sequence.   The
  618.      expression  "memory()"  means  send  the  "memory"  message to the Nil
  619.      object.
  620.  
  621.  
  622.      dObject allows the assignment of values and expressions  to  variables
  623.      through  the use of the assignment operator, denoted by the equals (=)
  624.      sign:
  625.  
  626.              dObject> v = 1+2*3;
  627.  
  628.  
  629.      dObject  recognizes  literal  expressions  beginning  with   the   '#'
  630.      character  and  defers  evaluation  of  the  expression until runtime.
  631.      Such  expressions  are  useful  when  you  are  actually  passing   an
  632.      expression  to  a method to evaluate later, such as using the built-in
  633.      "avg" method on a DBASE(tm) file.  The argument to  the  "avg"  method
  634.      is an  expression  to  evaluate  for  each  record  in  the file.  For
  635.      example, the following statements print  the  average  length  of  the
  636.      "lname" field within a DBASE(tm) file:
  637.  
  638.              dObject> db = new(Dbffile,"patient");
  639.              dObject> ? avg(db,#len(trim(lname)));
  640.  
  641.  
  642.      Passing  the  literal  expression #len(trim(lname))) instructs dObject
  643.      to defer evaluating the expression until the "avg" method  runs;    if
  644.      you  forget  the '#' sign before the expression, dObject will evaluate
  645.      the expression and pass the resulting Int value to  the  "avg"  method
  646.      as an argument, which will result in an error !
  647.  
  648.  
  649.      3.8 Program Control Statements
  650.  
  651.      dObject  provides  the  "for",  "while"  and  "switch"  statements  to
  652.      control the flow of program execution, all of  which  are  similar  to
  653.      their counterparts   in   the  C  programming  language.    The  "for"
  654.      statement  executes  a  block  of  statements   while   an   iteration
  655.      expression is true:
  656.  
  657.  
  658.  
  659.                                      - 11 -
  660.  
  661.  
  662. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  663.  
  664.  
  665.              /*
  666.                      demonstrate the for statement
  667.              */
  668.              for(i=0;i<10;i=i+1) ? i;
  669.  
  670.  
  671.      In  this  case,  dObject  will  execute the first statement in the for
  672.      expression, i=0, and then execute the statements in  the  block  after
  673.      the for  expression.  After each pass through the block, the statement
  674.      i=i+1 will be executed, and the expression i<10  evaluated.    If  the
  675.      expression  is  true  dObject  will  continue to execute the statement
  676.      block.  Execution  stops  whenever  the  expression  is  found  to  be
  677.      false.   After  the  for  statement is completed any variables used in
  678.      the statements will still exist;  in the above  example  i  will  have
  679.      the value of 11 after the for statement executes.
  680.  
  681.  
  682.      The  "while"  statement  executes  a  block  of  statements  while  an
  683.      expression evaluates to logical "true":
  684.  
  685.              /*
  686.                      demonstrate the while statement
  687.              */
  688.              i = 1;
  689.              while(i < 10) {
  690.                      ? " i = ",i;
  691.                      i = i+1;
  692.              }
  693.  
  694.  
  695.      The  "switch"  statement  is  similar  to  the  one  found  in  the  C
  696.      programming  language.  An  expression  is  evaluated and then matched
  697.      against the values found in a series of "case" statements.  The  first
  698.      case matching the expression value is executed:
  699.  
  700.  
  701.              /*
  702.                      demonstrate the switch statement
  703.              */
  704.              i = 3;
  705.              switch(i) {
  706.                      case 1:    ? "i is one ";
  707.                      case 2:    ? "i is two ";
  708.                      case 3:    ? "i is three ";
  709.                      case 4:    ? "i is four ";
  710.              }
  711.  
  712.  
  713.      In the  above  example  only  the  statement  ?    "i is three " would
  714.      execute within the switch.
  715.  
  716.  
  717.  
  718.  
  719.                                      - 12 -
  720.  
  721.  
  722.                                                  Chapter 3: dObject Statements
  723.  
  724.  
  725.      3.9 Editing Text Files
  726.  
  727.      dObject provides a built-in full screen text editor for  creating  and
  728.      modifying text  files,  including dObject source files.  To invoke the
  729.      editor, issue the "edit" command followed by the name of the  file  in
  730.      the current  directory  to  edit.    dObject  will  supply  a  default
  731.      extension of ".DO" for the file  to  make  it  easy  to  edit  dObject
  732.      source files.    For  example,  to  edit the file "test.do", issue the
  733.      command:
  734.  
  735.              dObject> edit test;
  736.  
  737.  
  738.      dObject will invoke the text editor in the current  window,  which  by
  739.      default is  the  full  screen.   Editing can occur in other windows by
  740.      first creating the window and the issuing the  "edit"  command.    The
  741.      built-in  editor  is  similar  to  the  WordStar(tm)  text  editor and
  742.      responds to the following keystroke commands:
  743.  
  744.  
  745.      FUNCTION                                          KEY
  746.  
  747.      View dObject help for word at cursor              Ctrl-F1
  748.      Move cursor right one character                   right arrow
  749.      Move cursor left one character                    left arrow
  750.      Move cursor up one line                           up arrow
  751.      Move cursor down one line                         down arrow
  752.      Scroll up one line                                Ctrl-W
  753.      Scroll down one line                              Ctrl-Z
  754.      Move cursor right one word                        Ctrl-Right arrow
  755.      Move cursor left one word                         Ctrl-A
  756.      Move cursor to right end of line                  End
  757.      Move cursor to left end of line                   Home
  758.      Move cursor to top of window                      Ctrl-Home
  759.      Move cursor to bottom of window                   Ctrl-End
  760.      Move cursor up one screen                         PgUp
  761.      Move cursor down one screen                       PgDn
  762.      Move cursor to top of file                        Ctrl-PgUp
  763.      Move cursor to bottom of file                     Ctrl-PgDn
  764.      Delete character at cursor                        Del, Ctrl-G
  765.      Delete character left of cursor                   Backspace
  766.      Delete word at cursor                             Ctrl-T
  767.      Delete line at cursor                             Ctrl-Y
  768.      Delete left from cursor to start of line          Ctrl-Q T
  769.      Delete right from cursor to start of line         Ctrl-Q Y
  770.      Mark beginning of block                           Ctrl-K B
  771.      Mark end of block                                 Ctrl-K K
  772.      Copy (insert) marked block at cursor              Ctrl-K C
  773.      Move (insert) marked block at cursor              Ctrl-K V
  774.      Delete marked block                               Ctrl-K Y
  775.      Write marked block to diskfile                    Ctrl-K W
  776.      Write marked block to printer                     Ctrl-K P
  777.  
  778.  
  779.                                      - 13 -
  780.  
  781.  
  782. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  783.  
  784.  
  785.      Block select on/off                               Ctrl-K M
  786.      Copy block to pastebuffer                         Ctrl-K I
  787.      Move block to pastebuffer                         Ctrl-K Y
  788.      Paste                                             Ctrl-U
  789.      Search                                            Ctrl-F3 or Ctrl-Q F
  790.      Search again                                      Shift-F3 or Ctrl-O
  791.      Replace                                           F4
  792.      Replace again                                     Shift-F4 or Ctrl-L
  793.  
  794.      The key assignments for the editor are contained in the file  "do.cfg"
  795.      that is  loaded  at  runtime by dObject.  You can change these default
  796.      combinations by  calling  the  Nil::setupKeyboard()  method  from  the
  797.      dObject  prompt,  changing  the key assignments using the menu choices
  798.      provided, and then saving the  current  key  configuration  using  the
  799.      String::saveConfig method.    The  following  example illustrates this
  800.      procedure:
  801.  
  802.              dObject> setupKeyboard();
  803.              dObject> saveConfig("new.cfg");
  804.              dObject> exit;
  805.              C:\DOBJECT:> rename do.cfg old.cfg
  806.              C:\DOBJECT:> rename new.cfg do.cfg
  807.  
  808.  
  809.      From within the Nil::setupKeyboard() method, a series of menu  choices
  810.      will  be  presented  that allow you to choose the particular functions
  811.      within  the  editor  to  be  re-assigned  to  a   key   or   keystroke
  812.      combination.   To  redefine  a  command's  keystroke(s), highlight the
  813.      menu item for the command using the arrow keys and press  Enter.    In
  814.      the  input  box  that  appears,  you  can  define  one  or two sets of
  815.      keystrokes for the command.  Press Enter to skip over  the  first  set
  816.      of  keystrokes,  or  press the new key combination for the first setup
  817.      and then press Enter.  When the cursor is in the second column,  press
  818.      Enter  to  skip  the  second  setup,  or  press  a new key combination
  819.      followed by Enter.  To abort this process at any time  press  the  Esc
  820.      key.
  821.  
  822.  
  823.      Your  application  can  load  a special .CFG file at runtime using the
  824.      String::loadConfig method and passing it  the  name  of  the  file  to
  825.      load.   The  file  should be one of the supplied .CFG files that comes
  826.      with dObject, or a .CFG file you  have  created  using  the  procedure
  827.      described above.
  828.  
  829.  
  830.      Comprehensive  on-line  help  for  editor  commands  is available from
  831.      within the  editor  by  pressing  the  F1  key.    Help  for   dObject
  832.      statements  and  built-in classes and methods is available from within
  833.      the editor by placing the cursor on a dObject keyword, class name,  or
  834.      method name and pressing the Ctrl-F1 key.
  835.  
  836.  
  837.  
  838.  
  839.                                      - 14 -
  840.  
  841.  
  842.                                                  Chapter 3: dObject Statements
  843.  
  844.  
  845.      3.10 Input and Output Statements
  846.  
  847.      The  "?"  statement prints the value of an expression onto the current
  848.      window, followed by a carriage return and line feed:
  849.  
  850.              dObject> ? 1+1;
  851.              2
  852.              dObject>
  853.  
  854.  
  855.      The String::accept() method provides a simple way to  write  a  prompt
  856.      and read Strings from the keyboard:
  857.  
  858.              dObject> line = accept("enter value> ");
  859.  
  860.  
  861.      For  a  detailed  description  of the input, output, and file handling
  862.      capabilities of dObject, refer  to  the  chapters  titled  "Files  and
  863.      Devices" and "Windows and Menus" later in this manual.
  864.  
  865.  
  866.      3.11 Output Logs
  867.  
  868.      dObject  will  also  log  the  output  from  the "?" command to a file
  869.      and/or an attached printer using the built-in log feature.    Pressing
  870.      the  ALT-P  key  combination  will  display  a  popup menu showing the
  871.      current on/off status of the logs to  the  printer  and  to  the  file
  872.      PROLOG.LOG.   To  toggle the status from off to on and vice versa, use
  873.      the arrow keys to position the menu bar, and press the RETURN  key  to
  874.      toggle the  value.    Press the ESC key to exit the menu and return to
  875.      the dObject prompt.
  876.  
  877.  
  878.      3.12 Environment Variables
  879.  
  880.      dObject maintains a small set of environment  variables  that  can  be
  881.      set  using  the  String::set()  method  and interrogated by the "show"
  882.      command.  These environment variables are:
  883.  
  884.  
  885.      VARIABLE     DEFAULT     DESCRIPTION
  886.  
  887.      echo         F           when true, causes dObject to echo the
  888.                               statement just about to be executed to the
  889.                               current window
  890.      hyperhelp    T           when true, allows use of Ctrl-F1 key from
  891.                               within editor  to access dObject help stored
  892.                               in HELP.DBF file; when false, disables
  893.                               Ctrl-F1
  894.      newline      nl          dObject will print this value at the end of
  895.                               each "?" statement
  896.      prompt       "dObject>"  the String to be used as the command prompt
  897.  
  898.  
  899.                                      - 15 -
  900.  
  901.  
  902. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  903.  
  904.  
  905.      softseek     F           when true, all String comparisons return true
  906.                               (T) if  a "partial match" occurs; that is if
  907.                               the first string being compared is a
  908.                               substring of second string.  when off,
  909.                               dObject returns true only if the strings
  910.                               being compared are identical, including
  911.                               trailing blanks
  912.      space        ""          dObject will print this value between
  913.                               expressions in the "?"  statement; normally
  914.                               set to a null String
  915.      status       T           when true, status lines appear for text
  916.                               editor,  window resize, etc. when false,
  917.                               turns off display of all status lines
  918.      step         F           when true, causes dObject to pause between
  919.                               executing statements and print the message:
  920.                               Press SPACE to continue, ESC to abort...
  921.                               pressing the space key executes the next
  922.                               statement pressing the ESC key returns to the
  923.                               dObject> prompt
  924.  
  925.      To set an enviroment variable to a value, use the String::set  method,
  926.      with the "self" argument set to the name of the SET variable:
  927.  
  928.              dObject> set("echo",T);
  929.  
  930.  
  931.      For example, to change the dObject prompt, set the prompt variable:
  932.  
  933.              dObject> set("prompt","--> ");
  934.              -->
  935.  
  936.  
  937.      To  show  the  value  of  all the environment variables, use the "show
  938.      set" command:
  939.  
  940.              dObject> show set;
  941.              echo=logical(false)
  942.              step=logical(false)
  943.              softseek=logical(false)
  944.              status=logical(true)
  945.              hyperhelp=logical(true)
  946.              prompt=string("dObject> ")
  947.              space=char(' ')
  948.  
  949.  
  950.      The value of a particular set variable is  available  by  calling  the
  951.      String::set()  method with self set to the name of the set variable to
  952.      retrieve and with no other arguments:
  953.  
  954.              dObject> ? set("echo");
  955.              F
  956.  
  957.  
  958.  
  959.                                      - 16 -
  960.  
  961.  
  962.                                                  Chapter 3: dObject Statements
  963.  
  964.  
  965.      To show all the currently defined dObject  variables,  use  the  "show
  966.      variables" command:
  967.  
  968.              dObject> a = 1;
  969.              dObject> b = 2;
  970.              dObject> show variables;
  971.              a=1
  972.              b=2
  973.  
  974.  
  975.      To  show  all the classes you have defined in a dObject session beyond
  976.      the built-in classes, use the "show classes"  command  (refer  to  the
  977.      next chapter for a description of how to create these classes):
  978.  
  979.              dObject> show classes;
  980.  
  981.  
  982.      To  show  all  the  methods  currently defined, use the "show methods"
  983.      command.
  984.  
  985.  
  986.      3.13 The RETURN Statement
  987.  
  988.      The return statement is used to return a value from a  dObject  method
  989.      back to   a  calling  program.    The  format  of  this  statement  is
  990.      return(exp), where exp is any dObject expression as  described  above.
  991.      The  use  of  this statement is appropriate only when defining you own
  992.      dObject classes and methods, a topic that is described  in  detail  in
  993.      the next chapter.
  994.  
  995.  
  996.  
  997.  
  998.                              4.0 dObject Classes
  999.  
  1000.      4.1 Objects
  1001.  
  1002.      dObject  provides  a  powerful  facility  for  you  to  write  complex
  1003.      applications using the "Object" paradigm.  With this way of  thinking,
  1004.      you  define  an  object as something within the problem you are trying
  1005.      to  solve  that  you  want  the  computer  to  represent   and   store
  1006.      information about.    For  example,  in  a  small  business  accouting
  1007.      system, the objects might include Companies,  Departments,  Employees,
  1008.      Products, and  Accounts, to name but a few.  Each of these objects has
  1009.      a certain correct behavior in the computer, such as a behavior to  add
  1010.      a  new Employee to a Company, or a behavior for calculating the profit
  1011.      from the sale of a Product to a Customer.
  1012.  
  1013.  
  1014.      In dObject,  the  object  types  within  the  application  are  called
  1015.      "Classes",  and  the  rules  that  tell the computer how a class is to
  1016.      behave are called "Methods".  Each class has a set of methods that  it
  1017.  
  1018.  
  1019.                                      - 17 -
  1020.  
  1021.  
  1022. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1023.  
  1024.  
  1025.      knows  about  that  allow  it  to  perform  calculations on the class.
  1026.      dObject provides a large library of built in classes,  each  with  its
  1027.      own  set  of  methods,  that  allow you to create complex applications
  1028.      right away.  However, to fully exploit the  power  of  object-oriented
  1029.      programming,  you  will eventually want to create your own classes and
  1030.      methods that apply directly to the problems you want to  solve.    You
  1031.      create  these  new  classes and methods by building them on top of the
  1032.      existing classes and methods.
  1033.  
  1034.  
  1035.      4.2 Class Definitions
  1036.  
  1037.      To create a new object class, use the "inherit" message on an  already
  1038.      existing dObject class:
  1039.  
  1040.              inherit(Parentclass,Newclass,variables);
  1041.  
  1042.  
  1043.      where   "Newclass"   is   the   name  of  the  new  class  to  define,
  1044.      "Parentclass" is the class to inherit  from,  and  "variables"  is  an
  1045.      array of  strings  that  name instance variables within the class.  In
  1046.      dObject, the names of classes must  always  begin  with  an  uppercase
  1047.      letter, followed  by  upper or lower-case characters or numerals.  For
  1048.      example, the statement:
  1049.  
  1050.              inherit(Date,Mydate,["julian"]);
  1051.  
  1052.  
  1053.      You should use the "Nil"  class  as  a  parent  class  that  does  not
  1054.      inherit data or methods from any parent.
  1055.  
  1056.  
  1057.      To create a variable of a given class type, use the "new" message:
  1058.  
  1059.              v = new(Class,arguments)
  1060.  
  1061.  
  1062.      where  "v"  is  the name of the variable to create, and "Class" is the
  1063.      object class of the variable.  For example, to create a  new  instance
  1064.      of  the "Mydate" class and store it into a variable named "d", use the
  1065.      statement:
  1066.  
  1067.              d = new(Mydate);
  1068.  
  1069.  
  1070.      dObject  provides  a  number  of  base  classes  as  building  blocks,
  1071.      including:
  1072.  
  1073.           * Nil - an empty class
  1074.  
  1075.           * Int - 2-byte signed integers
  1076.  
  1077.  
  1078.  
  1079.                                      - 18 -
  1080.  
  1081.  
  1082.                                                     Chapter 4: dObject Classes
  1083.  
  1084.  
  1085.           * Long - 4 byte signed integers
  1086.  
  1087.           * Real - floating point numbers
  1088.  
  1089.           * Char - single characters
  1090.  
  1091.           * String - strings of characters (up to 64K in length)
  1092.  
  1093.           * Logical - true (T) or false (F)
  1094.  
  1095.           * Date - dates
  1096.  
  1097.           *  Array  -  an array of object at locations indicated by an
  1098.           index
  1099.  
  1100.           * Collection - an ordered collection of objects
  1101.  
  1102.           * File - DOS ASCII text  files  and  devices  (such  as  the
  1103.           printer)
  1104.  
  1105.           *  Exp  -  literal dObject expressions that can be passed as
  1106.           arguments
  1107.  
  1108.           * Dbffile - DBASE files
  1109.  
  1110.           * Ndxfile - DBASE index files
  1111.  
  1112.           * Address - addresses of other objects
  1113.  
  1114.      The class of any dObject variable can always be found by  sending  the
  1115.      object the built-in "class" message:
  1116.  
  1117.              dObject> ? class(5/10/91);
  1118.              Date
  1119.              dObject> ? class("this is a test");
  1120.              String
  1121.              dObject> ? class(T);
  1122.              Logical
  1123.  
  1124.  
  1125.      4.3 Method Definitions
  1126.  
  1127.      To create a named method for a class, use the format:
  1128.  
  1129.              method Class::name(self,arguments)
  1130.              {
  1131.                      statements...
  1132.              }
  1133.  
  1134.  
  1135.  
  1136.  
  1137.  
  1138.  
  1139.                                      - 19 -
  1140.  
  1141.  
  1142. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1143.  
  1144.  
  1145.      Values  are  returned  to  the  calling program through the use of the
  1146.      "return" statement.  This should be the last statement  executed  from
  1147.      within a  method.  Methods that do not use a "return" statement have a
  1148.      return value of Nil.
  1149.  
  1150.  
  1151.      The special variable "self" always refers to the specific instance  of
  1152.      the object  that  the  method  is  being  performed on.  You can treat
  1153.      "self" as any other argument in the calling sequence.  For example:
  1154.  
  1155.              method Mydate::asString(self)
  1156.              {
  1157.                      return(asString(slot(self,"julian"));
  1158.              }
  1159.  
  1160.  
  1161.      defines a method for  the  "Mydate"  class  to  convert  itself  to  a
  1162.      String.
  1163.  
  1164.  
  1165.      To  define an operator for a class, use the character representing the
  1166.      operator as the method name.  For example, to define the '+'  operator
  1167.      for the Mydate class:
  1168.  
  1169.              method Mydate::+(self,d)
  1170.              {
  1171.                      return(asDate(julian(self) + julian(d)));
  1172.              }
  1173.  
  1174.  
  1175.      Variables  within  a  class  can be set by using the "replace" method,
  1176.      and referenced by the "slot" method. However, these  two  methods  are
  1177.      only available  from  within  methods  defined  for  the  class!  This
  1178.      implements an important feature of object-oriented programming:   data
  1179.      hiding.   Using  data hiding, it is good programming form to provide a
  1180.      method that returns the value of a variable within  a  class,  instead
  1181.      of allowing  a calling program to access that variable directly.  That
  1182.      way, if the implementation of the object changes at some  later  date,
  1183.      and  the  variables  within the class change, only the methods for the
  1184.      class need to understand the change  !    The  "outside  world"  still
  1185.      accesses information about the class through the methods.
  1186.  
  1187.  
  1188.      4.4 Private Methods
  1189.  
  1190.      By  default,  methods  defined  using  the  syntax described above are
  1191.      "public" in scope - they are available to any  other  method  or  main
  1192.      program that  wants to use them.  In some cases, however, you may wish
  1193.      to define methods that are hidden from other methods in the  same  way
  1194.      that variables  are  hidden.  dObject lets you do this by substituting
  1195.      the keyword "private" for "method" in  the  method  definition.    The
  1196.      following example shows how to define a private method for a class:
  1197.  
  1198.  
  1199.                                      - 20 -
  1200.  
  1201.  
  1202.                                                     Chapter 4: dObject Classes
  1203.  
  1204.  
  1205.              private Mydate::yearPlusOne(self)
  1206.              {
  1207.                      return(year(self)+1);
  1208.              }
  1209.  
  1210.  
  1211.  
  1212.      In  the  example  above, the "yearPlusOne" method is only available to
  1213.      other methods of the Mydate class.  Attempts to call it from a  method
  1214.      of  another  class  or  from  a  main  program  will generate an error
  1215.      message.
  1216.  
  1217.  
  1218.      The following example illustrates the use of a private method:
  1219.  
  1220.  
  1221.      /*
  1222.              demo of a private method for a class
  1223.              private methods are only callable from within a method for a class
  1224.      */
  1225.      inherit(Nil,Temp,[]);
  1226.  
  1227.      private Temp::testPrivate(self)
  1228.      {
  1229.              ? "within testPrivate";
  1230.      }
  1231.  
  1232.      method Temp::test(self)
  1233.      {
  1234.              ? "enter Temp::test";
  1235.              testPrivate(self);
  1236.              ? "exit Temp::test";
  1237.      }
  1238.  
  1239.      v = new(Temp);
  1240.      test(v); % this will work, Temp::testPrivate will be called by Temp::test
  1241.      ? "the next statement will cause an error !...";
  1242.      testPrivate(v); % this will cause an error !
  1243.  
  1244.  
  1245.      4.5 Friend Classes
  1246.  
  1247.      In some cases, you may wish to share the variables and/or the  private
  1248.      methods defined  for  a  class  with  another  class.    In this case,
  1249.      dObject provides the Exp::friend() method to allow such access.    The
  1250.      following  example  shows  how  to  define  one  class  as a friend of
  1251.      another:
  1252.  
  1253.      /*
  1254.              demo of a private method for a class
  1255.              private methods are only callable from within a method for a class
  1256.      */
  1257.  
  1258.  
  1259.                                      - 21 -
  1260.  
  1261.  
  1262. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1263.  
  1264.  
  1265.      inherit(Nil,Temp,[]);
  1266.      inherit(Nil,Temp2,[]);
  1267.  
  1268.      /*
  1269.              defining class Temp2 as a friend of class Temp
  1270.              means that methods of Temp2 can access variable and private
  1271.              methods of Temp
  1272.      */
  1273.      friend(Temp,Temp2);
  1274.  
  1275.      /*
  1276.              define a private method for Temp
  1277.      */
  1278.      private Temp::testPrivate(self)
  1279.      {
  1280.              ? "within Temp::testPrivate()";
  1281.      }
  1282.  
  1283.      /*
  1284.              define a public method for Temp2 that creates a variable of
  1285.              type Temp and calls a private method for it
  1286.      */
  1287.      method Temp2::test(self)
  1288.      {
  1289.              ? "enter Temp2::test";
  1290.              v = new(Temp);
  1291.              testPrivate(v); % this won't work unless Temp2 is a friend of Temp !
  1292.              ? "exit Temp2::test";
  1293.      }
  1294.  
  1295.      v = new(Temp2);
  1296.      test(v);
  1297.  
  1298.  
  1299.      4.6 Inheritance
  1300.  
  1301.      dObject stores variables for classes you define by allocating  storage
  1302.      for  a  variable  of  its  parent  class type, and storage for all the
  1303.      variables defined in the "inherit"  statement  for  its  class.    For
  1304.      example,  consider  a  class  called "Time" that inherits its behavior
  1305.      from the  Date  class.    The  "Time"  class  also  contains  internal
  1306.      variables   for  hours,  minutes,  and  seconds,  as  defined  in  the
  1307.      following statement:
  1308.  
  1309.  
  1310.              dObject> inherit(Date,Time,["hours","minutes","seconds"]);
  1311.  
  1312.  
  1313.      A new variable of type "Time" can be constructed as follows:
  1314.  
  1315.  
  1316.              dObject> t = new(Time,7/20/1990,1,2,3);
  1317.  
  1318.  
  1319.                                      - 22 -
  1320.  
  1321.  
  1322.                                                     Chapter 4: dObject Classes
  1323.  
  1324.  
  1325.      Internally, the variable "t" would be stored as  an  object  of  class
  1326.      "Time", with  4  internal  variables.    The first variable is of type
  1327.      Date (the parent class), with the value of 7/20/1990.   The  remaining
  1328.      variables  are  the  values  for  "hours", "minutes", and "seconds" as
  1329.      defined in the inherit statement above, with values of  1,  2,  and  3
  1330.      respectively.
  1331.  
  1332.  
  1333.      dObject  classes  "inherit"  all  the variables and methods from their
  1334.      parent class.  If you send a message to a  variable  of  a  class  you
  1335.      create  and  a  method  for  the message has not been defined, dObject
  1336.      will begin searching backwards through the parent class(es) to try  to
  1337.      find a  method  definition  it  can  use.    If a method is found, the
  1338.      variable storing the parent class  value  is  passed  to  the  method,
  1339.      without any  of  the  variables  for the original class.  This process
  1340.      continues until no more parent classes are found.
  1341.  
  1342.  
  1343.      For example, if you send the "asString" message to a Time variable  as
  1344.      defined  below,  and  you have not defined a version of "asString" for
  1345.      the Time class, then dObject will take the parent Date value and  send
  1346.      it the "asString" message:
  1347.  
  1348.  
  1349.              dObject> inherit(Date,Time,["hours","minutes","seconds"]);
  1350.              dObject> t = new(Time,7/20/1991,1,2,3);
  1351.              dObject> ? asString(t);
  1352.              7/20/1991
  1353.  
  1354.  
  1355.      4.7 Parameter Passing
  1356.  
  1357.      dObject  normally  passes arguments to methods by creating an internal
  1358.      stack and pushing the value for all the arguments to the  method  onto
  1359.      it.   This  is  exactly  the  way  the  C  language  calls  functions.
  1360.      However, in dObject, this implies that you  cannot  internally  change
  1361.      the  value  of  a  variable  within a class, but must instead return a
  1362.      copy of the variable containing the change.  This  leads  to  an  easy
  1363.      error to make:
  1364.  
  1365.      /*
  1366.              define a class for Money
  1367.      */
  1368.      inherit(Int,Money,["cents"]);
  1369.  
  1370.      method Money::setCents(self,c)
  1371.      {
  1372.              return(replace(slot(self,"cents"),i));
  1373.      }
  1374.  
  1375.  
  1376.      /*
  1377.  
  1378.  
  1379.                                      - 23 -
  1380.  
  1381.  
  1382. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1383.  
  1384.  
  1385.              create a variable of type Money
  1386.      */
  1387.      m = new(Money);
  1388.      setCents(m,100); % this is wrong !
  1389.  
  1390.  
  1391.      While  it  may appear simple to set a Money variable to a value from a
  1392.      calling program, be  careful  !    You  must  remember  to  store  the
  1393.      returned copy of the variable back into itself:
  1394.  
  1395.      /*
  1396.              assign "m" a value the wrong way
  1397.      */
  1398.      setCents(m,100); % this returns a copy of m with "cents"=100 that is lost
  1399.  
  1400.      /*
  1401.              assign "m" a value the right way
  1402.      */
  1403.      m = setCents(m,100); % this stores the copy back in m !
  1404.  
  1405.  
  1406.      dObject  allows a program to circumvent the need to always pass copies
  1407.      of variables around through the use of the Address class.   Using  the
  1408.      "address-of"  operator (the "&" symbol, as in C), you can instead pass
  1409.      the address of a variable to a method:
  1410.  
  1411.              setCents(&m,100);
  1412.  
  1413.  
  1414.      However, to do  this  correctly,  the  method  must  be  expecting  an
  1415.      address of  a variable and not a copy of the variable itself.  This is
  1416.      done by using an asterik before the argument in the method  definition
  1417.      wherever an  address  is  to be used.  The following example shows how
  1418.      to define and use a method that replaces  the  value  of  an  internal
  1419.      class variable directly in memory:
  1420.  
  1421.  
  1422.      /*
  1423.              define a new version of the setCents method that
  1424.              replaces a memory location and does not return a copy
  1425.      */
  1426.      method Money::setCents(*self,c)
  1427.      {
  1428.              replace(slot(*self,"cents"),c);
  1429.      }
  1430.  
  1431.      /*
  1432.              now this is OK !
  1433.      */
  1434.      m = new(Money);
  1435.      setCents(&m,100); % m will be updated in-place
  1436.  
  1437.  
  1438.  
  1439.                                      - 24 -
  1440.  
  1441.  
  1442.                                                     Chapter 4: dObject Classes
  1443.  
  1444.  
  1445.      To  access  the  contents  of  an address, use the "contents" operator
  1446.      (the asterik character), again just like in the C language:
  1447.  
  1448.              dObject> ?class(&1);
  1449.              Address
  1450.              dObject> ? *&1;
  1451.              1
  1452.  
  1453.  
  1454.      4.8 Space Management
  1455.  
  1456.      To  reclaim  the  space  used  by  a  variable,  send  an   expression
  1457.      containing the name of the variable the "release" message:
  1458.  
  1459.              dObject> a = 1;
  1460.              dObject> release(#a);
  1461.  
  1462.  
  1463.      To  reclaim the space used by a method definition once it is no longer
  1464.      needed by your program, use the "release" method  of  the  Exp  class.
  1465.      Send  the message to the Class name for the method you wish to delete,
  1466.      and pass the message a String argument containing the method name:
  1467.  
  1468.              dObject> release(Myint,"value");
  1469.  
  1470.  
  1471.      To reclaim all the space used by a class,  including  its  definition,
  1472.      its methods, and any variables, use the releaseClass method:
  1473.  
  1474.              dObject> releaseClass(Mydate);
  1475.  
  1476.  
  1477.      4.9 Input and Output
  1478.  
  1479.      To  print the value of an object (while executing the "?" command, for
  1480.      example), dObject first sends the object the "asString" method to  try
  1481.      to convert  it to a String.  If this succeeds, the resulting String is
  1482.      printed and the next object to  print  is  processed.    Each  of  the
  1483.      built-in  classes  provided  in dObject has an asString method defined
  1484.      for it.  If there is no such method for the  class,  dObject  attempts
  1485.      to print  a  representation  of  the internal form of the object.  For
  1486.      user defined classes, this printout will be of the form:
  1487.  
  1488.              object(Class,[slot(Name,Value)...])
  1489.  
  1490.  
  1491.      4.10 Sample Application
  1492.  
  1493.      As a  final  example  of  how  to  create  classes  and  methods,  the
  1494.      following  program  completes the implementation of the abstract class
  1495.      "Money" used in the examples above:
  1496.  
  1497.  
  1498.  
  1499.                                      - 25 -
  1500.  
  1501.  
  1502. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1503.  
  1504.  
  1505.      /*
  1506.              this is an example of a class to handle money as an abstract type
  1507.              first, define a Money class with a variable to hold an
  1508.              integer number of cents; this will be converted into
  1509.              dollars and cents whenever the Money variable is converted to a String
  1510.      */
  1511.      inherit(Int,Money,[]);
  1512.  
  1513.      /*
  1514.              set the number of cents in self
  1515.              NOTE: self must be passed by address for this to work !
  1516.      */
  1517.      method Money::setCents(*self,c)
  1518.      {
  1519.              replace(parent(*self),c);
  1520.      }
  1521.  
  1522.      /*
  1523.              return the number of dollars in self
  1524.      */
  1525.      method Money::dollars(self)
  1526.      {
  1527.              return(self/100);
  1528.      }
  1529.  
  1530.      /*
  1531.              return the number of cents in self
  1532.      */
  1533.      method Money::cents(self)
  1534.      {
  1535.              return(self - (dollars(self)*100));
  1536.      }
  1537.  
  1538.      /*
  1539.              the "asString" method allows a Money variable to be converted
  1540.              to a String and/or printed
  1541.      */
  1542.      method Money::asString(self)
  1543.      {
  1544.              return("$ "+asString(dollars(self))+"."+format(cents(self),"%02d"));
  1545.      }
  1546.  
  1547.      method Int::asMoney(self)
  1548.      {
  1549.              return(new(Money,self));
  1550.      }
  1551.  
  1552.      /*
  1553.              test case
  1554.      */
  1555.      m = new(Money,100);
  1556.      setCents(&m,104);
  1557.  
  1558.  
  1559.                                      - 26 -
  1560.  
  1561.  
  1562.                                                     Chapter 4: dObject Classes
  1563.  
  1564.  
  1565.      ? m;
  1566.      ? asMoney(m+1);
  1567.      ? asMoney(m*10);
  1568.  
  1569.  
  1570.  
  1571.  
  1572.                              5.0 Numeric Classes
  1573.  
  1574.      5.1 Numeric Classes
  1575.  
  1576.      dObject supports three types of  numeric  classes:    Int,  Long,  and
  1577.      Real.   Class  Int  supports  signed  2-byte  integer  values  between
  1578.      -32,768 to 32,767.  Long values are signed 4-byte integer  numbers  in
  1579.      the range  -2147483648  to  2147483647.  Real numbers are 8 bytes long
  1580.      and in the range -1e+307 to 1e+308.  dObject  provides  operators  for
  1581.      performing arithmetic  on Int, Long and Real classes.  For example, to
  1582.      add two integers together to get a third, send the "plus"  message  to
  1583.      the first  integer,  using the second integer as an argument.  This is
  1584.      accomplished in the statement:
  1585.  
  1586.              dObject> n = 1+2;
  1587.              dObject> ? n;
  1588.              3
  1589.  
  1590.  
  1591.      where the variable "n" will be  assigned  the  value  Int  3.  dObject
  1592.      responds  to  the  '+'  (plus),  '-'  (minus), '*' (multiply), and '/'
  1593.      (divide) operators on  both  Int  and  Real  variables.    Mixed  mode
  1594.      arithmetic  is  also  supported  for  calculations  involving Ints and
  1595.      Reals, in  which  case  the  result  is  always  Real.    Mixed   mode
  1596.      arithmetic involving Long values is not supported.
  1597.  
  1598.  
  1599.      A  wide  variety  of  named messages are supplied for numeric classes,
  1600.      including:
  1601.  
  1602.  
  1603.           * max(self,Int), max(self,Real),  max(self,Long)  -  returns
  1604.           max value of self and arg
  1605.  
  1606.           *  min(self,Int),  min(self,Real),  min(self,Long) - returns
  1607.           min value of self and arg
  1608.  
  1609.           * abs(self) - returns absolute value of self (Int or Real)
  1610.  
  1611.           * log(self) - returns log base e of self (Real)
  1612.  
  1613.           * log10(self) - returns log base 10 of self (Real)
  1614.  
  1615.           * sqrt(self) - returns square root of self(Real)
  1616.  
  1617.  
  1618.  
  1619.                                      - 27 -
  1620.  
  1621.  
  1622. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1623.  
  1624.  
  1625.           * sin(self) - returns sine of self (Real, self in radians)
  1626.  
  1627.           * cos(self) - returns cosine of self(Real, self in radians)
  1628.  
  1629.           * tan(self)  -  returns  tangent  of  self  (Real,  self  in
  1630.           radians)
  1631.  
  1632.      Refer   to   the  accompanying  file  "CLASSLIB.DOC"  for  a  complete
  1633.      description of the built-in numeric methods and operators.
  1634.  
  1635.  
  1636.      Of course, you can define new methods for the numeric classes  if  you
  1637.      so choose.    This  example show defining a new method "factorial" for
  1638.      the Long class, which calls itself recursively:
  1639.  
  1640.      /*
  1641.              define a recursive factorial method for the "Long" class
  1642.      */
  1643.      method Long::factorial(self)
  1644.      {
  1645.              if(self <= 1L) return(self);
  1646.              else return(self*factorial(self-1L));
  1647.      }
  1648.  
  1649.      /*
  1650.              calculate some factorials
  1651.      */
  1652.      i = 0;
  1653.      while(i < 10) {
  1654.              ? i," ",factorial(asLong(i));
  1655.              i = i+1;
  1656.      }
  1657.  
  1658.  
  1659.  
  1660.                            6.0 Logical Operations
  1661.  
  1662.      6.1 Logical Operations
  1663.  
  1664.      dObject provides the built-in class  "Logical"  for  representing  the
  1665.      boolean values  of "true" and "false".  dObject also provides built-in
  1666.      operators for a variety of comparison operations between classes  that
  1667.      result in a Logical value:
  1668.  
  1669.  
  1670.      OPERATOR  NAME           CLASS(ES)                DESCRIPTION
  1671.  
  1672.      [eq][eq]  equal          all                      returns true if self
  1673.                                                        and arg are equal
  1674.      !=        not equal      all                      returns true if self
  1675.                                                        and arg are not
  1676.                                                        equal
  1677.  
  1678.  
  1679.                                      - 28 -
  1680.  
  1681.  
  1682.                                                  Chapter 6: Logical Operations
  1683.  
  1684.  
  1685.      >         greater than   Int,Real,Char,String     returns true if self
  1686.                                                        greater than arg
  1687.      >=        greater than/eqInt,Real,Char,String     returns true if self
  1688.                                                        greater than  or
  1689.                                                        equal to arg
  1690.      <         less than      Int,Real,Char,String     returns true if self
  1691.                                                        less than arg
  1692.      <=        less than/eq   Int,Real,Char,String     returns true if self
  1693.                                                        less than or  equal
  1694.                                                        to arg
  1695.  
  1696.      To  create  a  logical  value, use the "new" method, a literal Logical
  1697.      value, or make an assignment using one  of  the  comparison  operators
  1698.      above:
  1699.  
  1700.              dObject> l = new(Logical);
  1701.              dObject> l = T;
  1702.              dObject> l = 1 < 2;
  1703.  
  1704.  
  1705.  
  1706.                          7.0 Characters and Strings
  1707.  
  1708.      7.1 Characters and Strings
  1709.  
  1710.      dObject   provides  the  built-in  classes  "Char"  and  "String"  for
  1711.      handling character calculations.  A Char literal should  be  a  single
  1712.      character  surrounded  by single quotes, while a String literal can be
  1713.      any number of characters delimited by the double quote character.
  1714.  
  1715.  
  1716.      To create a string, use the "new" method or make an  assignment  using
  1717.      a literal:
  1718.  
  1719.              dObject> s = new(String);
  1720.              dObject> s2 = "this is a string";
  1721.  
  1722.  
  1723.      To find the length of a String, use the "len" method:
  1724.  
  1725.              dObject> ? len(String);
  1726.              16
  1727.  
  1728.  
  1729.      Strings  respond  to the normal set of comparison operators (==,!=, <,
  1730.      <=,>, >=).  Trailing blanks can  be  removed  from  a  String  by  the
  1731.      "trim" method:
  1732.  
  1733.              dObject> ?  len(trim("aaa "));
  1734.              3
  1735.  
  1736.  
  1737.  
  1738.  
  1739.                                      - 29 -
  1740.  
  1741.  
  1742. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1743.  
  1744.  
  1745.      Strings can be concatenated together using the "+" operator:
  1746.  
  1747.              dObject> a = "string1";
  1748.              dObject> b = "string2";
  1749.              dObject> ? a + " and " + b;
  1750.              "string1 and string2"
  1751.  
  1752.  
  1753.      To access a particular character in a String, use the "at" method:
  1754.  
  1755.              dObject> c = at("test",2);
  1756.              dObject> ? c;
  1757.              e
  1758.  
  1759.  
  1760.      The  same  built-in  text editor that is used by the "edit" command to
  1761.      edit text files is callable as a method of the  String  class.    This
  1762.      causes  the contents of the string to be edited in the current window,
  1763.      and returns the value of the edited string.  For a  read-only  display
  1764.      of  the string contents in the current window with no editing allowed,
  1765.      use the "display" method:
  1766.  
  1767.              dObject> s = "this is a string";
  1768.              dObject> edited_string = edit(s);
  1769.              dObject> display(edited_string);
  1770.  
  1771.  
  1772.      dObject also provides String methods to interface directly  with  DOS.
  1773.      A  DOS  command  within  a  String  can be executed using the "system"
  1774.      method, passing it the command string in the "self"  argument  and  an
  1775.      Int  indicator  for  resetting the screen to the state it was in prior
  1776.      to executing the command string (0=do not reset, 1=reset):
  1777.  
  1778.              dObject> cmd = "dir *.do";
  1779.              dObject> system(cmd,0);
  1780.  
  1781.  
  1782.      The value of a DOS environment variable can be  accessed  through  the
  1783.      "envSymbol" method:
  1784.  
  1785.              dObject> s = envSymbol("path");
  1786.  
  1787.  
  1788.      A named file can be edited using the "editFile" method:
  1789.  
  1790.              dObject> editFile("test.txt");
  1791.  
  1792.  
  1793.      The  contents  of  an existing DOS file can be placed in a String very
  1794.      quickly by the "fileString" method, where "self" is the  name  of  the
  1795.      file:
  1796.  
  1797.  
  1798.  
  1799.                                      - 30 -
  1800.  
  1801.  
  1802.                                              Chapter 7: Characters and Strings
  1803.  
  1804.  
  1805.              dObject> text = fileString("test.do");
  1806.              dObject> edit(text);
  1807.  
  1808.  
  1809.      String  values can be converted to Int, Real, Date, and Logical values
  1810.      using  the  "asInt",  "asReal",  "asDate",  and  "asLogical"   methods
  1811.      respectively:
  1812.  
  1813.              dObject> s = "123";
  1814.              dObject> ? class(asInt(s))," ",asInt(s);
  1815.              Int 123
  1816.  
  1817.  
  1818.      String  values  can  be  forced  to  upper  or  lower  case  using the
  1819.      "asUpper" and "asLower" methods:
  1820.  
  1821.              dObject> s = "This is a Test";
  1822.              dObject> ? asUpper(s);
  1823.              THIS IS A TEST
  1824.              dObject> ? asLower(s)
  1825.              this is a test
  1826.  
  1827.  
  1828.      dObject provides a  pattern  match  function  in  the  String::match()
  1829.      method.   This method matches a pattern against the string and returns
  1830.      a Int index specifying the portion of  the  string  that  matched  the
  1831.      pattern:
  1832.  
  1833.              dObject> s = "This is a test";
  1834.              dObject> ? match(s,"is a test");
  1835.              6
  1836.  
  1837.  
  1838.      The  special  codes  recogized by the String::match() method are those
  1839.      recognized by the UNIX GREP utility and include:
  1840.  
  1841.  
  1842.           * ' start-of-line anchor
  1843.  
  1844.           * '$' end-of-line anchor
  1845.  
  1846.           * '.' matches any character
  1847.  
  1848.           * '[' start a character class
  1849.  
  1850.           * ']' end a character class
  1851.  
  1852.           * ' negates character class if 1st char
  1853.  
  1854.           * '*' Keene closure (matches 0 or more)
  1855.  
  1856.           * '+' positive closure (1 or more)
  1857.  
  1858.  
  1859.                                      - 31 -
  1860.  
  1861.  
  1862. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1863.  
  1864.  
  1865.           * '?' optional closure (0 or more)
  1866.  
  1867.      There are other String methods provided by dObject that are  described
  1868.      in CLASSLIB.DOC.
  1869.  
  1870.  
  1871.  
  1872.                                   8.0 Dates
  1873.  
  1874.      8.1 Dates
  1875.  
  1876.      dObject  provides  a  rich set of methods for handling dates using the
  1877.      built-in "Date" class.  To create a new date variable, use  the  "new"
  1878.      method, or a date literal:
  1879.  
  1880.              dObject> d = new(Date);
  1881.              dObject> d = 5/1/91;
  1882.  
  1883.  
  1884.      The  built  in Nil::date() method returns the current system date as a
  1885.      Date variable.
  1886.  
  1887.  
  1888.      You can access the month, day, and year parts  of  a  date  using  the
  1889.      "month", "day",  "year",  and  "century"  methods.    For example, the
  1890.      expression below will return just the year of the current date  as  an
  1891.      Int:
  1892.  
  1893.              dObject> ? year(date());
  1894.  
  1895.  
  1896.      You  can  also  set  the  values  of these parts of the date using the
  1897.      "setMonth", "setDay", "setYear", and "setCentury" methods:
  1898.  
  1899.              dObject> d = date();
  1900.              dObject> d = setMonth(d,1);
  1901.  
  1902.  
  1903.      dObject supports the addition and subtraction of an integer number  of
  1904.      days  to  and  from  a  Date variable, and also supports conversion of
  1905.      Dates to a julian value.  For example, to find the  date  that  is  30
  1906.      days from the current date:
  1907.  
  1908.              dObject> future_date = date()+30;
  1909.  
  1910.  
  1911.      The  "asJulian"  method  returns  a Real value that is the julian date
  1912.      for a Date value.    The  Real::asDate  method  performs  the  inverse
  1913.      operation, returning a Date for a given julian number:
  1914.  
  1915.              dObject> j = asJulian(date());
  1916.              dObject> d = asDate(j);
  1917.  
  1918.  
  1919.                                      - 32 -
  1920.  
  1921.  
  1922.                                                               Chapter 8: Dates
  1923.  
  1924.  
  1925.      Dates  can be formatted into and from String variables in a variety of
  1926.      formats, including  international  formats.    dObject  provides   the
  1927.      "asString"  method  for the Date class and the "asDate" method for the
  1928.      String class to accomplish these format conversions.  In both cases  a
  1929.      format  String  is  passed to the method indicating how the date is to
  1930.      be formatted or scanned:
  1931.  
  1932.      /*
  1933.              test the dObject date conversion functions
  1934.      */
  1935.      ? date();
  1936.      s = asString(date(),"MMM DD/YY");
  1937.      ? s;
  1938.      d = asDate(s,"MMM DD/YY");
  1939.      ? d;
  1940.  
  1941.  
  1942.      The valid date format codes recognized by dObject are:
  1943.  
  1944.           * CC 2-digit century
  1945.  
  1946.           * YY 2-digit year
  1947.  
  1948.           * MM 2-digit month
  1949.  
  1950.           * MMM 3-char month (JAN, FEB, etc.)
  1951.  
  1952.           * DD 2-digit day
  1953.  
  1954.      These codes can be used in format strings to  indicate  how  the  date
  1955.      should be  formatted  or  scanned.    For  example,  the following are
  1956.      typical date formats:
  1957.  
  1958.           * YY.MM.DD
  1959.  
  1960.           * CCYY.MM.DD
  1961.  
  1962.           * MM/DD/YY
  1963.  
  1964.           * DD-MM/YY
  1965.  
  1966.           * DD-MM/CCYY
  1967.  
  1968.           * MMM DD/YY
  1969.  
  1970.      As a final example, the following code implements the  "cday"  method,
  1971.      which  returns  a  String  that  contains  the name of the day for the
  1972.      date:
  1973.  
  1974.      /*
  1975.              this is an example of how to define methods for the built-in
  1976.              Date class
  1977.  
  1978.  
  1979.                                      - 33 -
  1980.  
  1981.  
  1982. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  1983.  
  1984.  
  1985.              "cday" returns a character string naming the day
  1986.      */
  1987.      method Date::cday(self)
  1988.      {
  1989.              if(dow(self) == 1) return("Sunday");
  1990.              if(dow(self) == 2) return("Monday");
  1991.              if(dow(self) == 3) return("Tuesday");
  1992.              if(dow(self) == 4) return("Wednesday");
  1993.              if(dow(self) == 4) return("Thursday");
  1994.              if(dow(self) == 5) return("Friday");
  1995.              if(dow(self) == 6) return("Saturday");
  1996.      }
  1997.  
  1998.  
  1999.      /*
  2000.              define the same function, using the "switch" statement
  2001.      */
  2002.      method Date::cday2(self)
  2003.      {
  2004.              switch(dow(self)) {
  2005.                      case 1:    return("Sunday");
  2006.                      case 2:    return("Monday");
  2007.                      case 3:    return("Tuesday");
  2008.                      case 4:    return("Wednesday");
  2009.                      case 5:    return("Thursday");
  2010.                      case 6:    return("Friday");
  2011.                      case 7:    return("Saturday");
  2012.              }
  2013.      }
  2014.  
  2015.      /*
  2016.              call the methods defined above
  2017.      */
  2018.      ? cday(date());
  2019.      ? cday2(date());
  2020.  
  2021.  
  2022.  
  2023.                             9.0 Windows and Menus
  2024.  
  2025.      dObject provides classes that allow you to write  professional-looking
  2026.      applications that  use  character-cell  windows and pop-up menus.  The
  2027.      "?" command, the "say" method of the Window class,  and  the  built-in
  2028.      "Field" base class all send their output to a specified window.
  2029.  
  2030.  
  2031.      9.1 Windows
  2032.  
  2033.      Windows  are created using the "new" method, and passing it the window
  2034.      number, window attribute, frame  attribute,  title,  left  corner  y,x
  2035.      position, and  the  y and x lengths for the window as parameters.  The
  2036.      x,y co-ordinates of a window or  other  object  within  a  window  are
  2037.  
  2038.  
  2039.                                      - 34 -
  2040.  
  2041.  
  2042.                                                   Chapter 9: Windows and Menus
  2043.  
  2044.  
  2045.      always  counted down and right from the (0,0) origin in the upper left
  2046.      corner.  For example, to create a new window that is the size  of  the
  2047.      entire  screen,  contains  the title "test window", and has a white on
  2048.      blue display color and a lite blue border:
  2049.  
  2050.              dObject> w = new(Window,1,31,3,"test window",0,0,24,80);
  2051.  
  2052.  
  2053.      Color attributes can be calculated from the following formula:
  2054.  
  2055.           * Choose one foreground color and one background color
  2056.  
  2057.           * Add the corresponding integer values below.
  2058.  
  2059.           * Add 128 if  you  want  whatever  is  displayed  with  that
  2060.           attribute to blink
  2061.  
  2062.      BACKGROUND               FOREGROUND
  2063.  
  2064.      Black          0         Black          0
  2065.      Blue           16        Blue           1
  2066.      Green          32        Green          2
  2067.      Cyan           48        Cyan           3
  2068.      Red            64        Red            4
  2069.      Magenta        80        Magenta        5
  2070.      Brown          96        Brown          6
  2071.      White          112       White          7
  2072.      Grey           8
  2073.      Light Blue     24
  2074.      Light Green    40
  2075.      Light Red      72
  2076.      Light Magenta  88
  2077.      Yellow         104
  2078.      White (High    120
  2079.      Intensity)
  2080.  
  2081.      You  can  also  include  the  supplied  file  "COLORS.DO" that defines
  2082.      symbolic names for the colors.
  2083.  
  2084.  
  2085.      When  the  "new"  method  creates  the  window  it  also  displays  it
  2086.      immediately  and  makes  the  new  window the current window. To write
  2087.      output to a window, you must first make the window current.   You  can
  2088.      do this explicitly by sending the window the "shiftwindow" message:
  2089.  
  2090.              dObject> shiftwindow(w);
  2091.  
  2092.  
  2093.      You  can always obtain the current window as a Window object through a
  2094.      call to the Nil::currentWindow() method:
  2095.  
  2096.              dObject> shiftwindow(currentWindow());
  2097.  
  2098.  
  2099.                                      - 35 -
  2100.  
  2101.  
  2102. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2103.  
  2104.  
  2105.      You can clear the contents of a window with the "clear" message.    To
  2106.      remove a window from the screen, send it the "remove" message:
  2107.  
  2108.              dObject> remove(w);
  2109.  
  2110.  
  2111.      To  interactively  resize  or  setup  the  color for a window, use the
  2112.      "resize" and  "setupColor"  methods.     These   methods   allow   for
  2113.      interactive  resizing  and  color  setup  using  the cursor keys and a
  2114.      color  display  that  shows  the  foreground  and  background   colors
  2115.      available as  well  as the color attribute number.  When interactively
  2116.      resizing a window, use the  following  keys  to  change  the  window's
  2117.      size:
  2118.  
  2119.  
  2120.           *  Width  -  Press  the  left  arrow  key to make the window
  2121.           narrower or the right arrow key to make it wider.   To  make
  2122.           changes  in larger increments, hold down the Ctrl key at the
  2123.           same time.  Use the end key to  expand  the  window  at  the
  2124.           start of the screen.
  2125.  
  2126.           *  Length  -  Press the up arrow key to decrease or the down
  2127.           arrow key to increase the length of the  window.    Use  the
  2128.           page  down  key  to  extend  the window to the bottom of the
  2129.           screen and the page up key to extend the window to  the  top
  2130.           of the screen.
  2131.  
  2132.      To  change the position of the window on the screen, use the following
  2133.      keys:
  2134.  
  2135.           * Shift-Up Up one row
  2136.  
  2137.           * Shift-Down Down one row
  2138.  
  2139.           * Shift-Right Right one column
  2140.  
  2141.           * Shift-left Left one column
  2142.  
  2143.           * Shift-Home To left screen edge
  2144.  
  2145.           * Shift-End To right screen edge
  2146.  
  2147.           * Shift-PgUp To top of screen
  2148.  
  2149.           * Shift-PgDn To bottom of screen
  2150.  
  2151.           * Ctrl-Home To top left screen corner
  2152.  
  2153.           * Ctrl-End To bottom left screen corner
  2154.  
  2155.           * Ctrl-PgUp To top right screen corner
  2156.  
  2157.  
  2158.  
  2159.                                      - 36 -
  2160.  
  2161.  
  2162.                                                   Chapter 9: Windows and Menus
  2163.  
  2164.  
  2165.           * Ctrl-PgDn To bottom right screen corner
  2166.  
  2167.      To setup the color for the window text, pass the setupColor method  an
  2168.      Int argument  of  0;   to setup the color of the frame, pass it an Int
  2169.      argument of 1.  For  example,  the  following  statement  invokes  the
  2170.      setup display for the color of the current window:
  2171.  
  2172.              dObject> setupColor(currentWindow(),0);
  2173.  
  2174.  
  2175.      dObject   creates  windows  with  a  default  frame  consisting  of  a
  2176.      single-width line border, and with the  window  title  centered  above
  2177.      the  window  in the border. to change this, you can use the "setFrame"
  2178.      message.  The first argument to setFrame is  the  color  attribute  of
  2179.      the  frame,  followed  by the title of the frame, the integer position
  2180.      to place the title counting from the left-hand  side  (a  value  of  0
  2181.      instructs   dObject  to  center  the  title),  and  finally  a  String
  2182.      containing 6 characters  to  build  frame  with  using  the  following
  2183.      convention:
  2184.  
  2185.           * 1st char:  Upper left corner
  2186.  
  2187.           * 2nd char:  Upper right corner
  2188.  
  2189.           * 3rd char:  Lower left corner
  2190.  
  2191.           * 4th char:  Lower right corner
  2192.  
  2193.           * 5th char:  Horizontal line
  2194.  
  2195.           * 6th char:  Vertical line
  2196.  
  2197.      For  example, to frame a window with the title "My Window" starting at
  2198.      position 3, with a white frame and a the '#' character for  a  border,
  2199.      use the message:
  2200.  
  2201.              dObject> setFrame(w,7,"My Window",3,"######");
  2202.  
  2203.  
  2204.      9.2 Output using SAY and GET
  2205.  
  2206.      dObject  provides  methods  to build full-screen data entry and review
  2207.      forms through the Int::say() and Window::say()  methods,  and  through
  2208.      the built-in  Field  base  class.   The SAY/GET facility in dObject is
  2209.      similar in function to the @ say and @ get commands  provided  by  the
  2210.      DBASE language.    In  dObject  these  methods  work  within a window,
  2211.      providing a way to create very sophisticated data handling forms.
  2212.  
  2213.  
  2214.      To produce output from an expression at a y,x point within  a  window,
  2215.      send  the  window  the  Int  y  coordinate,  the Int x coordinate, the
  2216.      expression to output, an Int length of the field to  display,  and  an
  2217.  
  2218.  
  2219.                                      - 37 -
  2220.  
  2221.  
  2222. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2223.  
  2224.  
  2225.      Int color attribute to display the expression in:
  2226.  
  2227.              dObject> say(currentWindow(),5,5,"this is a test",14,7);
  2228.  
  2229.  
  2230.      To  set  up  a  get  field for input, call the Exp::new method for the
  2231.      class "Field", and send it the Window to place the field in,  the  Int
  2232.      y  coordinate,  the Int x coordinate, a String name of the variable to
  2233.      place the result into, an Int length of the field to display, and  Int
  2234.      color attribute.    Make  sure  that  the  variable you will store the
  2235.      value into is already defined:
  2236.  
  2237.              dObject> a = "this is a test";
  2238.              dObject> new(Field,currentWindow(),6,6,"a",14,112);
  2239.  
  2240.  
  2241.      Alternatively, the field name can be the name of a DBASE field in  the
  2242.      currently active DBF file:
  2243.  
  2244.              dObject> db = new(Dbffile,"patient");
  2245.              dObject> new(Field,currentWindow(),6,6,"lname",14,112);
  2246.  
  2247.  
  2248.      The  Exp::new(Field,...)  method returns a variable of type Field that
  2249.      represents the field within the window.  Once defined, a list  of  get
  2250.      variables   can  be  read  in  a  full-screen  input  mode  using  the
  2251.      Window::read() method:
  2252.  
  2253.              dObject> read(currentWindow());
  2254.  
  2255.  
  2256.      Entering this mode causes  dObject  to  position  the  cursor  at  the
  2257.      beginning  of the first get field defined, and to wait for the user to
  2258.      enter new values for data fields and scroll  through  records  in  the
  2259.      current Dbffile.  The specific keys recognized are:
  2260.  
  2261.  
  2262.      KEY       ACTION         DESCRIPTION
  2263.  
  2264.      Esc       Escape         exits the form and returns to dObject>
  2265.                               prompt
  2266.      Home      Goto top       Positions the current DBF file at the
  2267.                               first record and displays it
  2268.      End       Goto bottom    Positions the current DBF file at the
  2269.                               last record and displays it
  2270.      PgUp      Prev  Record   Positions the current DBF file at the
  2271.                               previous record and displays it
  2272.      PgDn      Next Record    Positions the current DBF file at the
  2273.                               next record and displays it
  2274.      Tab       Next Field     Positions the cursor at the beginning of
  2275.                               the next display field
  2276.      Up        Up cursor      Positions the cursor up one line
  2277.  
  2278.  
  2279.                                      - 38 -
  2280.  
  2281.  
  2282.                                                   Chapter 9: Windows and Menus
  2283.  
  2284.  
  2285.      Down      Down cursor    Positions the cursor down one line
  2286.      Right     Right cursor   Positions the cursor right one space
  2287.                               within current display field
  2288.      Left      Left cursor    Positions the cursor left one space
  2289.                               within the current display field
  2290.      F10       Quit           exits the form and returns to dObject>
  2291.                               prompt
  2292.  
  2293.      You  can  modify  the  actions  associated with these or any other key
  2294.      while in read mode by calling the Int::onKey() method and  passing  it
  2295.      an expression  to  evaluate.  For example, the following example shows
  2296.      how to call the built-in text editor to edit the  contents  of  a  GET
  2297.      field by pressing the F8 key while in read mode:
  2298.  
  2299.  
  2300.      /*
  2301.              this method implements a callable text editor for the contents of
  2302.              a field
  2303.      */
  2304.      method Window::myEdit(self)
  2305.      {
  2306.              f = currentField(self);
  2307.              s = eval(asId(name(f)));
  2308.              if(class(s) == "String") {
  2309.                      w = new(Window,1,31,3,name(f),5,5,10,40);
  2310.                      display(s);
  2311.                      remove(w);
  2312.                      gotoField(self,f);
  2313.              }
  2314.      }
  2315.  
  2316.      db = new(Dbffile,"patient");
  2317.      new(Field,currentWindow(),6,6,"lname",14,112);
  2318.      onKey(w,F8,#myEdit(w));
  2319.      read(currentWindow());
  2320.  
  2321.  
  2322.      To  clear  the  existing  list of get variables from future reads, use
  2323.      the Window::clearGets() method:
  2324.  
  2325.              dObject> clearGets(currentWindow());
  2326.  
  2327.  
  2328.      The following example program shows setting up  two  get  fields  with
  2329.      prompts:
  2330.  
  2331.      /*
  2332.              sample full screen field output
  2333.      */
  2334.      w = new(Window,1,31,3,"",0,0,24,80);
  2335.      clearGets(2);
  2336.      a = "test";
  2337.  
  2338.  
  2339.                                      - 39 -
  2340.  
  2341.  
  2342. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2343.  
  2344.  
  2345.      b = "test2";
  2346.      say(w,5,5,"field a",7,7);
  2347.      say(w,6,5,"field b",7,7);
  2348.      new(Field,w,5,20,"a",10,112);
  2349.      new(Field,w,6,20,"b",10,112);
  2350.      read(w);
  2351.      remove(w);
  2352.  
  2353.  
  2354.      9.3 Pictures
  2355.  
  2356.      You  can  assign  a  picture  template  to a GET field that will cause
  2357.      dObject to  format  the  value  being  displayed  in  the  field,  and
  2358.      validate keystrokes  upon  entry to the field.  Do this by calling the
  2359.      Field::setPicture() method, and passing it  a  String  containing  the
  2360.      picture:
  2361.  
  2362.  
  2363.              dObject> a = "test";
  2364.              dObject> f = new(Field,w,5,20,"a",10,112);
  2365.              dObject> setPicture(f,"!!!!!!!!!!");
  2366.  
  2367.  
  2368.      dObject recognizes the following picture code characters:
  2369.  
  2370.           * !    -   Converts  letters  to  uppercase;    accepts  all
  2371.           characters
  2372.  
  2373.           * A - Allows letters only
  2374.  
  2375.           * L - Translates characters to logical values (T, t,  F,  f,
  2376.           Y, y, N, n)
  2377.  
  2378.           * N - Allows letters and numbers
  2379.  
  2380.           * 9 - Allows digits only
  2381.  
  2382.           *  X  -  Allows  numbers,  spaces, signs, and decimal points
  2383.           only
  2384.  
  2385.           * Other characters are copied literally into  the  displayed
  2386.           value
  2387.  
  2388.      The following example demonstrates the use of picture clauses:
  2389.  
  2390.  
  2391.      /*
  2392.              demonstrate the use of a picture within a GET field
  2393.      */
  2394.      w = currentWindow();
  2395.      clearGets(w);
  2396.      cls;
  2397.  
  2398.  
  2399.                                      - 40 -
  2400.  
  2401.  
  2402.                                                   Chapter 9: Windows and Menus
  2403.  
  2404.  
  2405.      a = "test";
  2406.      prompt = "Enter a value: ";
  2407.      say(w,5,5,prompt,len(prompt),7);
  2408.      f = new(Field,w,5,len(prompt)+5,"a",10,112);
  2409.      setPicture(f,"!!!!!!!!!!");
  2410.      read(w);
  2411.      ? "the value you entered was ",a;
  2412.  
  2413.  
  2414.      9.4 Key Codes
  2415.  
  2416.      The   special   key   codes   recognized  by  the  Window::read()  and
  2417.      Nil::inkey() methods are defined in the supplied file  KEYDEF.DO  (you
  2418.      can  include  this file in programs by using the #include preprocessor
  2419.      statement):
  2420.  
  2421.      #define   BACK_SPACE   "$08"
  2422.      #define   TAB          "$09"
  2423.      #define   ESC          "$1B"
  2424.      #define   CTRL_A       "$01"
  2425.      #define   CTRL_B       "$02"
  2426.      #define   CTRL_C       "$03"
  2427.      #define   CTRL_D       "$04"
  2428.      #define   CTRL_E       "$05"
  2429.      #define   CTRL_F       "$06"
  2430.      #define   CTRL_G       "$07"
  2431.      #define   CTRL_H       "$08"
  2432.      #define   CTRL_I       "$09"
  2433.      #define   CTRL_J       "$0A"
  2434.      #define   CTRL_K       "$0B"
  2435.      #define   CTRL_L       "$0C"
  2436.      #define   CTRL_M       "$0D"
  2437.      #define   CTRL_N       "$0E"
  2438.      #define   CTRL_O       "$0F"
  2439.      #define   CTRL_P       "$10"
  2440.      #define   CTRL_Q       "$11"
  2441.      #define   CTRL_R       "$12"
  2442.      #define   CTRL_S       "$13"
  2443.      #define   CTRL_T       "$14"
  2444.      #define   CTRL_U       "$15"
  2445.      #define   CTRL_V       "$16"
  2446.      #define   CTRL_W       "$17"
  2447.      #define   CTRL_X       "$18"
  2448.      #define   CTRL_Y       "$19"
  2449.      #define   CTRL_Z       "$1A"
  2450.      #define   RETURN       "$D"
  2451.      #define   HOME         "$4700"
  2452.      #define   END          "$4F00"
  2453.      #define   PGUP         "$4900"
  2454.      #define   PGDN         "$5100"
  2455.      #define   UP           "$4800"
  2456.      #define   DOWN         "$5000"
  2457.  
  2458.  
  2459.                                      - 41 -
  2460.  
  2461.  
  2462. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2463.  
  2464.  
  2465.      #define   RIGHT        "$4D00"
  2466.      #define   LEFT         "$4B00"
  2467.      #define   SHIFT_TAB    "$0F00"
  2468.      #define   INS          "$5200"
  2469.      #define   DEL          "$5300"
  2470.  
  2471.      #define   CTRL_HOME    "$7700"
  2472.      #define   CTRL_END     "$7500"
  2473.      #define   CTRL_PGUP    "$8400"
  2474.      #define   CTRL_PGDN    "$7600"
  2475.      #define   CTRL_RIGHT   "$7400"
  2476.      #define   CTRL_LEFT    "$7300"
  2477.  
  2478.      #define   ALT_1       "$7800"
  2479.      #define   ALT_2       "$7900"
  2480.      #define   ALT_3       "$7A00"
  2481.      #define   ALT_4       "$7B00"
  2482.      #define   ALT_5       "$7C00"
  2483.      #define   ALT_6       "$7D00"
  2484.      #define   ALT_7       "$7E00"
  2485.      #define   ALT_8       "$7F00"
  2486.      #define   ALT_9       "$8000"
  2487.      #define   ALT_0       "$8100"
  2488.      #define   ALT_MINUS   "$8200"
  2489.      #define   ALT_EQUAL   "$8300"
  2490.  
  2491.      #define   ALT_Q       "$1000"
  2492.      #define   ALT_W       "$1100"
  2493.      #define   ALT_E       "$1200"
  2494.      #define   ALT_R       "$1300"
  2495.      #define   ALT_T       "$1400"
  2496.      #define   ALT_Y       "$1500"
  2497.      #define   ALT_U       "$1600"
  2498.      #define   ALT_I       "$1700"
  2499.      #define   ALT_O       "$1800"
  2500.      #define   ALT_P       "$1900"
  2501.  
  2502.      #define   ALT_A       "$1E00"
  2503.      #define   ALT_S       "$1F00"
  2504.      #define   ALT_D       "$2000"
  2505.      #define   ALT_F       "$2100"
  2506.      #define   ALT_G       "$2200"
  2507.      #define   ALT_H       "$2300"
  2508.      #define   ALT_J       "$2400"
  2509.      #define   ALT_K       "$2500"
  2510.      #define   ALT_L       "$2600"
  2511.  
  2512.      #define   ALT_Z       "$2C00"
  2513.      #define   ALT_X       "$2D00"
  2514.      #define   ALT_C       "$2E00"
  2515.      #define   ALT_V       "$2F00"
  2516.      #define   ALT_B       "$3000"
  2517.  
  2518.  
  2519.                                      - 42 -
  2520.  
  2521.  
  2522.                                                   Chapter 9: Windows and Menus
  2523.  
  2524.  
  2525.      #define   ALT_N       "$3100"
  2526.      #define   ALT_M       "$3200"
  2527.  
  2528.      #define   F1           "$3B00"
  2529.      #define   F2           "$3C00"
  2530.      #define   F3           "$3D00"
  2531.      #define   F4           "$3E00"
  2532.      #define   F5           "$3F00"
  2533.      #define   F6           "$4000"
  2534.      #define   F7           "$4100"
  2535.      #define   F8           "$4200"
  2536.      #define   F9           "$4300"
  2537.      #define   F10          "$4400"
  2538.  
  2539.      #define   CTRL_F1      "$5E00"
  2540.      #define   CTRL_F2      "$5F00"
  2541.      #define   CTRL_F3      "$6000"
  2542.      #define   CTRL_F4      "$6100"
  2543.      #define   CTRL_F5      "$6200"
  2544.      #define   CTRL_F6      "$6300"
  2545.      #define   CTRL_F7      "$6400"
  2546.      #define   CTRL_F8      "$6500"
  2547.      #define   CTRL_F9      "$6600"
  2548.      #define   CTRL_F10     "$6700"
  2549.  
  2550.      #define   SHIFT_F1     "$5400"
  2551.      #define   SHIFT_F2     "$5500"
  2552.      #define   SHIFT_F3     "$5600"
  2553.      #define   SHIFT_F4     "$5700"
  2554.      #define   SHIFT_F5     "$5800"
  2555.      #define   SHIFT_F6     "$5900"
  2556.      #define   SHIFT_F7     "$5A00"
  2557.      #define   SHIFT_F8     "$5B00"
  2558.      #define   SHIFT_F9     "$5C00"
  2559.      #define   SHIFT_F10    "$5D00"
  2560.  
  2561.      #define   ALT_F1       "$6800"
  2562.      #define   ALT_F2       "$6900"
  2563.      #define   ALT_F3       "$6A00"
  2564.      #define   ALT_F4       "$6B00"
  2565.      #define   ALT_F5       "$6C00"
  2566.      #define   ALT_F6       "$6D00"
  2567.      #define   ALT_F7       "$6E00"
  2568.      #define   ALT_F8       "$6F00"
  2569.      #define   ALT_F9       "$7000"
  2570.      #define   ALT_F10      "$7100"
  2571.  
  2572.  
  2573.      9.5 Menus
  2574.  
  2575.  
  2576.  
  2577.  
  2578.  
  2579.                                      - 43 -
  2580.  
  2581.  
  2582. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2583.  
  2584.  
  2585.      dObject provides a pop-up menu  facility  in  the  built-in  Menu  and
  2586.      Linemenu classes.    Menus are created by passing the "new" method the
  2587.      Int y,x location of the upper left corner of the menu, the Int  length
  2588.      of  the  menu  (number of lines to show), the Int text and frame color
  2589.      attributes, a Collection of menu choices, and a String title.    Menus
  2590.      are  executed  using  the  "choice"  method containing an Int argument
  2591.      that specifies what choice to highlight upon entry to the menu.    The
  2592.      "choice"  method  returns the index of the menu item chosen within the
  2593.      Collection;  the calling program can retrieve the actual value  chosen
  2594.      by indexing the Collection with the "at" method.
  2595.  
  2596.      Menus  remain  displayed  in  the  current  Window  until the "remove"
  2597.      message is sent to them.  The following example  shows  putting  up  a
  2598.      menu of numeric values and asking the user to choose:
  2599.  
  2600.      /*
  2601.              create a menu using a Collection of choices
  2602.      */
  2603.      myCollection = [1.0,2.0,3,4,5,6,7,8,9];
  2604.      a= new(Menu,3,3,5,31,3,myCollection," test ");
  2605.      b = choice(a,1);
  2606.      remove(a);
  2607.      ? "result of menu is ",b;
  2608.  
  2609.      /*
  2610.              the actual value chosen is found by getting the value
  2611.              in the collection at index "b"
  2612.      */
  2613.      value = at(myCollection,b);
  2614.  
  2615.  
  2616.      To  exit the menu without making a choice, press the ESC key while the
  2617.      menu is active.  This causes the Menu::choice() method to return 0  as
  2618.      the chosen value.
  2619.  
  2620.  
  2621.      The  number  of  values in the Collection in a Menu can be much larger
  2622.      than the display size of the Menu.  When this  occurs,  the  user  can
  2623.      press  the  up  and  down arrow keys to scroll through the menu before
  2624.      making a choice with the "Enter" key.
  2625.  
  2626.  
  2627.  
  2628.      9.6 Line Menus
  2629.  
  2630.      dObject also provides a "Linemenu" class that  implements  lotus-style
  2631.      line menus  with  optional  help  lines.    You can create a line menu
  2632.      using the "new" method, and passing it the Int window  number  of  the
  2633.      window  to  create  for  the menu, an Int row and column for the upper
  2634.      left corner of the menu, an Int width of the  menu,  a  Collection  of
  2635.      values  to  put  in the menu, and a corresponding Collection of status
  2636.      lines to show for each menu choice.  When  the  menu  is  created  and
  2637.  
  2638.  
  2639.                                      - 44 -
  2640.  
  2641.  
  2642.                                                   Chapter 9: Windows and Menus
  2643.  
  2644.  
  2645.      shown  using the Linemenu::choice() method, the choices will be evenly
  2646.      spaced across the width of the menu in the first  line  of  the  menu,
  2647.      and  the  status line text for a given choice will be displayed on the
  2648.      second line, much  like  the  style  of  a  Lotus  1-2-3  menu.    The
  2649.      following example illustrates the use of the Linemenu class:
  2650.  
  2651.  
  2652.      /*
  2653.              demo of the Linemenu class
  2654.      */
  2655.      color = 54;
  2656.      width = 40;
  2657.      m = new(Linemenu,1,5,width,color,color,[1,2,3,4,5,6],
  2658.              ["first","second","third","fourth","fifth","sixth"]);
  2659.      c = choice(m);
  2660.      remove(m);
  2661.      ? "your choice was ",c;
  2662.  
  2663.  
  2664.      You  can  create  a  Linemenu  that  does  not  display  status  lines
  2665.      underneath the choices by passing an empty  Collection  to  "new"  for
  2666.      the status line text.  In this case a one-line menu will be created:
  2667.  
  2668.  
  2669.              m = new(Linemenu,1,5,5,54,54,[1,2,3,4,5,6],[]);
  2670.  
  2671.  
  2672.      9.7 Hypertext
  2673.  
  2674.      dObject  provides  the  capability  to  use the Window class described
  2675.      above to display hypertext built from DBASE data and index files.   To
  2676.      build  a  hypertext  string  that can be displayed or edited using the
  2677.      built-in text editor, use the Dbffile::htExpand() method.  The  "self"
  2678.      argument  to  this  method  is a Dbffile object that contains at least
  2679.      two text fields:  one field containing a one-word  topic  string,  and
  2680.      one  field containing the text to show whenever that topic is selected
  2681.      from within a display.    For  example,  the  supplied  dObject  files
  2682.      HELP.DBF,  HELP.DBT, and HELP.NDX are DBASE files that are used as the
  2683.      dictionary for the on-line help within the  text  editor  and  are  an
  2684.      example of suitable hypertext files:
  2685.  
  2686.              dObject> db = new(Dbffile,"help");
  2687.              dObject> displayStructure(db);
  2688.              Structure for:             HELP.DBF
  2689.              Number of records: 8
  2690.              Last update:               6/2/91
  2691.              Version:                   3
  2692.              Number of fields:  2
  2693.              Field              Field Name      Type    Width   Dec
  2694.              0          TOPIC           C           8       0
  2695.              1          TEXT            M          10       0
  2696.  
  2697.  
  2698.  
  2699.                                      - 45 -
  2700.  
  2701.  
  2702. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2703.  
  2704.  
  2705.      You  must  also  pass  an  Ndxfile object that is a DBASE index on the
  2706.      topic field, a String name of the text field to  use  in  the  Dbffile
  2707.      for  the text to show for a topic, an Int color to highlight the words
  2708.      in the string being converted that have topic entries in the  Dbffile,
  2709.      and a  String  containing  the  text to convert.  The method returns a
  2710.      String containing embedded control codes telling the  built-in  editor
  2711.      to highlight  the  topic  words  in  the  color  you have chosen.  The
  2712.      following example illustrates the proper calling sequence:
  2713.  
  2714.              dObject> db = new(Dbffile,"help");
  2715.              dObject> ndx = useIndex(db,"help");
  2716.              dObject> keylen = 32; % length of the topic field
  2717.              dObject> htext = htExpand(db,ndx,"text",31,keylen,
  2718.                      "this is some text");
  2719.  
  2720.  
  2721.      To  display  the  hypertext  within  the  current  window,   use   the
  2722.      String::display() method:
  2723.  
  2724.              dObject> display(htext);
  2725.  
  2726.  
  2727.      Calling  this  method  will display the text within the current window
  2728.      with words that have matching  entries  in  the  topic  field  of  the
  2729.      Dbffile highlighted  with  the  color attribute chosen above.  You can
  2730.      position the  cursor  using  the  normal  editor  keys,  and  you  can
  2731.      "follow"  the  hypertext link for a highlighed word by positioning the
  2732.      cursor on that word and pressing the CTRL-F1 key.  Pressing  this  key
  2733.      causes  dObject  to  execute  the String::onHyperKey() method with the
  2734.      contents of the "text" field for the  topic  that  was  found  in  the
  2735.      Dbffile.   You should always supply a version of String::onHyperKey as
  2736.      part of your hypertext application;   If  you  do  not,  pressing  the
  2737.      CTRL-F1  key  will have no effect will look for the word at the cursor
  2738.      in the HELP.DBF file.
  2739.  
  2740.  
  2741.      The following example shows how  to  define  the  String::onHyperKey()
  2742.      method  and  build  a  small  hypertext application using the supplied
  2743.      dObject HELP.DBF, HELP.NDX, and HELP.DBT files:
  2744.  
  2745.      /*
  2746.              this is a demo of dObject's hypertext display feature
  2747.              first, define a method to handle the "follow hyper link"
  2748.              key when it is pressed from a window
  2749.      */
  2750.      method String::onHyperKey(self)
  2751.      {
  2752.      /*
  2753.              create a window for the text
  2754.      */
  2755.              w = new(Window,1,31,31,"",8,8,10,40);
  2756.      /*
  2757.  
  2758.  
  2759.                                      - 46 -
  2760.  
  2761.  
  2762.                                                   Chapter 9: Windows and Menus
  2763.  
  2764.  
  2765.              the color attribute is the first character token in the string
  2766.      */
  2767.              color = asInt(token(self,#s));
  2768.      /*
  2769.              turn off the dObject hypertext help key (CTRL-F1) from within
  2770.              the display
  2771.      */
  2772.              set("hyperhelp",F);
  2773.      /*
  2774.              display the text
  2775.              to follow the link for a highlighted field, hit the SHIFT-F8 key
  2776.      */
  2777.              display(htExpand(db,index,"text",32,color,s));
  2778.              remove(w);
  2779.      }
  2780.  
  2781.      /*
  2782.              demo hypertext
  2783.      */
  2784.      #define COLOR 79
  2785.      db = new(Dbffile,"help");
  2786.      index = useIndex(db,"help");
  2787.      w = new(Window,1,31,31," Hypertext ",5,5,10,50);
  2788.      display(htExpand(db,index,"text",COLOR,32,":while for if then else dos"));
  2789.      remove(w);
  2790.      close(db);
  2791.  
  2792.  
  2793.  
  2794.                          10.0 Arrays and Collections
  2795.  
  2796.      10.1 Arrays
  2797.  
  2798.      dObject provides  classes  for  handling  Arrays  and  Collections  of
  2799.      objects.   The primary difference between an Array and a Collection is
  2800.      that a Collection can be considered an ordered  list  of  values  that
  2801.      can  easily be inserted into, appended to , and deleted from, while an
  2802.      Array is similar to a DBASE array that can be easily indexed by a  set
  2803.      of  integer indexes, but not easily ordered, inserted into, or deleted
  2804.      from.  Both Collections and Arrays can contain  any  kind  of  dObject
  2805.      class, including   other   Collections   and  Arrays.    There  is  no
  2806.      pre-defined limit on the size of an Array or Collection, but  attempts
  2807.      to use more memory than is available will cause an error message.
  2808.  
  2809.  
  2810.      Arrays  are  similar  to  those  provided  in  the  DBASE  programming
  2811.      language.  An  array  element  can  be  stored  or  retrieved  from  a
  2812.      specific  location  within  an  array through the use of the "replace"
  2813.      and "at" messages, passing a  Collection  of  integer  indexes  as  an
  2814.      argument.
  2815.  
  2816.  
  2817.  
  2818.  
  2819.                                      - 47 -
  2820.  
  2821.  
  2822. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2823.  
  2824.  
  2825.      For  example,  to  create  an  array of 10 elements and store a String
  2826.      value in the first location:
  2827.  
  2828.              dObject> a = new(Array,[10]);
  2829.              dObject> replace(a,[1],"this is the first element");
  2830.              dObject> ? at(a,[1]);
  2831.              t
  2832.  
  2833.  
  2834.      To create multi-dimensional arrays, create the array  with  more  than
  2835.      one  dimension  in  the dimension Collection, and address it with more
  2836.      than one element in the index Collection:
  2837.  
  2838.              dObject> a = new(Array,[3,3,3]);
  2839.              dObject> replace(a,[1,1,1],"this is the first element");
  2840.  
  2841.  
  2842.      /*
  2843.              this is a test of dObject's Array class
  2844.      */
  2845.      method Array::print(self)
  2846.      {
  2847.              i = 0;
  2848.              while(i < len(self)) {
  2849.                      print(at(self,i));
  2850.                      print(' ');
  2851.                      i = i+1;
  2852.              }
  2853.      }
  2854.  
  2855.      /*
  2856.              create a single-dimension array of 4096 locations
  2857.      */
  2858.      a = new(Array,[4096]);
  2859.      i = 0;
  2860.      while(i < 4096) {
  2861.              replace(a,[i],i);
  2862.              i = i+1;
  2863.      }
  2864.      ? a;
  2865.  
  2866.  
  2867.      10.2 Collections
  2868.  
  2869.      dObject's Collection class provides an advanced way to  store  ordered
  2870.      collections of   objects.      The   Collection  class  comes  with  a
  2871.      comprehensive set of built-in methods for adding,  deleting,  finding,
  2872.      and replacing  members  within  the  collection.  Collections are most
  2873.      easily  created  using  the  literal  convention  of   surrounding   a
  2874.      comma-separated list of literal values with brackets:
  2875.  
  2876.              dObject> myCollection = [1,2,3,4,5];
  2877.  
  2878.  
  2879.                                      - 48 -
  2880.  
  2881.  
  2882.                                             Chapter 10: Arrays and Collections
  2883.  
  2884.  
  2885.      Empty Collections can also be created using the Exp::new() method:
  2886.  
  2887.  
  2888.              dObject> myCollection = new(Collection);
  2889.              dObject> ? myCollection;
  2890.              []
  2891.  
  2892.  
  2893.      As  with  Arrays,  members  of  a  Collection can be any valid dObject
  2894.      class, including other Collections:
  2895.  
  2896.              dObject> myCollection = [[1,2,3],[4,5,6],[7,8,9]];
  2897.  
  2898.  
  2899.      To add a value to the end of a Collection, use the "append" method:
  2900.  
  2901.              dObject> myCollection = [1,2,3];
  2902.              dObject> myCollection = append(myCollection,4);
  2903.              dObject> ? myCollection;
  2904.              [1,2,3,4]
  2905.  
  2906.  
  2907.      To replace an existing value within a Collection,  use  the  "replace"
  2908.      method,  passing it a value to replace and the new value to replace it
  2909.      with:
  2910.  
  2911.              dObject> myCollection = [1,2,3];
  2912.              dObject> myCollection = replace(myCollection,1,32);
  2913.              dObject> ? myCollection;
  2914.              [32,2,3]
  2915.  
  2916.  
  2917.      The number of values within a Collection can be  found  by  the  "len"
  2918.      method:
  2919.  
  2920.              dObject> ? len([1,2,3,4,5]);
  2921.              5
  2922.  
  2923.  
  2924.      The  first  value  in  a  Collection  is  called  the  "head"  of  the
  2925.      Collection, and the remaining Collection without the  head  is  called
  2926.      the "tail":
  2927.  
  2928.              dObject> ? myCollection = [1,2,3];
  2929.              dObject> ? head(myCollection);
  2930.              1
  2931.              dObject> ? tail(myCollection);
  2932.              [2,3]
  2933.  
  2934.  
  2935.  
  2936.  
  2937.  
  2938.  
  2939.                                      - 49 -
  2940.  
  2941.  
  2942. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  2943.  
  2944.  
  2945.      Individual  values  within  a Collection can be retrieved using an Int
  2946.      index, but this is not nearly as efficient as using an Array for  this
  2947.      purpose:
  2948.  
  2949.              dObject> ? at(["one","two","three"],2);
  2950.              two
  2951.  
  2952.  
  2953.      The  last  element  in  a  collection  is  available  using the "last"
  2954.      method:
  2955.  
  2956.              dObject> ? last([1,2,3,4]);
  2957.              4
  2958.  
  2959.  
  2960.      The maximum and minimum values from within a Collection can  be  found
  2961.      with the "max" and "min" methods respectively:
  2962.  
  2963.              dObject> ? max([1,2,3]);
  2964.              3
  2965.  
  2966.  
  2967.      A  Collection  can  be  filtered into another Collection by the "sort"
  2968.      and "unique" methods.  The "sort" method returns a Collection that  is
  2969.      the sorted  version  of  the  variable  it  is called on.  The sort is
  2970.      accomplished using the ">"  operator  on  whatever  class  is  in  the
  2971.      Collection, and is done in ascending order:
  2972.  
  2973.              dObject> ? sort([3,1,4,6,5,2]);
  2974.              [1,2,3,4,5,6]
  2975.  
  2976.  
  2977.      The  "unique"  method  returns  a  Collection consisting of the unique
  2978.      elements in the Collection it is called on:
  2979.  
  2980.              dObject> ? unique([1,1,2,2,3,3,4,4,5,5,6,6]);
  2981.              [1,2,3,4,5,6]
  2982.  
  2983.  
  2984.      The following example demonstrates many of the methods  available  for
  2985.      handling Collections:
  2986.  
  2987.      /*
  2988.              this is a demonstration of dObject's Collection class
  2989.      */
  2990.      a = [5,3,9,5,100,44,5];
  2991.      ? "Collection is ",a;
  2992.      ? "length is ",len(a);
  2993.      ? "reversed is ",reverse(a);
  2994.      ? "third element is ",at(a,3);
  2995.      ? "last element is ",last(a);
  2996.      ? "with 100 removed is ",remove(a,100);
  2997.  
  2998.  
  2999.                                      - 50 -
  3000.  
  3001.  
  3002.                                             Chapter 10: Arrays and Collections
  3003.  
  3004.  
  3005.      ? "substitute 1005 for 5 is ",replace(a,5,1005);
  3006.      ? "is 44 in collection ?: ",44 $ a;
  3007.      ? "sorted array is ",sort(a);
  3008.      ? "unique array is ",unique(a);
  3009.      ? "unique sorted Collection is ",sort(unique(a));
  3010.      ? "sum of elements is ",sum(a);
  3011.      ? "minimum value is ",min(a);
  3012.      ? "maximum value is ",max(a);
  3013.      ? "average value is ",avg(a);
  3014.  
  3015.      /*
  3016.              fill a collection
  3017.      */
  3018.      a = [];
  3019.      i = 0;
  3020.      while(i < 10) {
  3021.              a = append(a,i);
  3022.              i = i+1;
  3023.      }
  3024.      ? a;
  3025.  
  3026.  
  3027.  
  3028.                            11.0 Files and Devices
  3029.  
  3030.      11.1 Files and Devices
  3031.  
  3032.      dObject  allows  output  to  DOS text files and to devices such as the
  3033.      printer through the built-in "File"  class.    Files  are  created  by
  3034.      passing  the  "new"  method  the  name  of  the file to create, an Int
  3035.      switch indicating if the file is to  be  opened  in  read,  write,  or
  3036.      append  mode  (1,2,  or  3  respectively),  an  Int containing the DOS
  3037.      attributes of the file, and an Int specifying what to do if  the  file
  3038.      already exists:
  3039.  
  3040.              dObject> f = new(File,"new.out",1,0,0);
  3041.  
  3042.  
  3043.      Constant  definitions  for the open mode, the DOS file attributes, and
  3044.      the creation option flag are provided in the file IODEF.DO:
  3045.  
  3046.      /*
  3047.              some constant definitions for new(File,...)
  3048.      */
  3049.      /* File Attributes */
  3050.      #define FA_RDONLY "$01"    /* Read only file       */
  3051.      #define FA_HIDDEN "$02"    /* Hidden file          */
  3052.      #define FA_SYSTEM "$04"    /* System file          */
  3053.      #define FA_SUBDIR "$10"    /* Subdirectory         */
  3054.      #define FA_ARCH   "$20"    /* Archive file         */
  3055.      #define FA_NORMAL "$40"    /* Normal file - No read/write restrictions */
  3056.  
  3057.  
  3058.  
  3059.                                      - 51 -
  3060.  
  3061.  
  3062. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3063.  
  3064.  
  3065.      /* File usage Modes */
  3066.      #define FM_ACCESS_WO "$0001"  /* write only           */
  3067.      #define FM_ACCESS_RW "$0002"  /* read/write           */
  3068.      #define FM_ACCESS_RO "$0004"  /* read only            */
  3069.      #define FM_SH_DENYRW "$0010"  /* deny read/write mode */
  3070.      #define FM_SH_DENYWR "$0020"  /* deny write mode      */
  3071.      #define FM_SH_DENYRD "$0030"  /* deny read mode       */
  3072.      #define FM_SH_DENYNO "$0040"  /* deny none mode       */
  3073.  
  3074.      /* Exclusively for OS2 and DOS >4.0 */
  3075.      #define FM_RETURNERR "$2000"  /* return error rather than call crit hand. */
  3076.      #define FM_WRITETHRU "$4000"  /* write through        */
  3077.  
  3078.      /* Creation Flags */
  3079.      /* Actions if file exists (low nibble) :   */
  3080.      #define CR_EX_FAIL "$00"
  3081.      #define CR_EX_OPEN "$01"
  3082.      #define CR_EX_REPLACE      "$02"
  3083.  
  3084.      /* Actions if file doesn't exist (high nibble):    */
  3085.      #define CR_NOEX_FAIL       "$00"
  3086.      #define CR_NOEX_CREATE     "$10"
  3087.  
  3088.  
  3089.      dObject  maintains  "current"  input  and  output  devices  which  are
  3090.      normally the  keyboard and the screen respectively.  These devices can
  3091.      be redirected to files  through  the  "readDevice"  and  "writeDevice"
  3092.      methods:
  3093.  
  3094.              dObject> writeDevice(f);
  3095.  
  3096.  
  3097.      Files  can  be  flushed  and  closed  through  the "flush" and "close"
  3098.      methods.  For example, to open a file and write a line  of  output  to
  3099.      it:
  3100.  
  3101.  
  3102.      You  can  read  a  character  from  the current input device using the
  3103.      Nil::readchar() method, which returns the next  character  as  a  Char
  3104.      variable.   To  read  a  complete keycode from the keyboard as an Int,
  3105.      use the  Nil::inkey()  method.    The  key  definitions  returned   by
  3106.      Nil::inkey() are defined in the include file "keydef.do".
  3107.  
  3108.      If  you  use  Nil::readchar()  to read characters, you can "push back"
  3109.      characters into the input  buffer  using  the  Char::unread()  method.
  3110.      This  method pushes its Char argument back into the input buffer where
  3111.      it can be read later using Nil::readchar().
  3112.  
  3113.  
  3114.      The following example describes how to create a file and write  output
  3115.      to it:
  3116.  
  3117.  
  3118.  
  3119.                                      - 52 -
  3120.  
  3121.  
  3122.                                                  Chapter 11: Files and Devices
  3123.  
  3124.  
  3125.      /*
  3126.              this is a demonstration of dObject's file handling capabilities
  3127.      */
  3128.      f = new(File,"new.out",1,0,0);
  3129.      writeDevice(f);
  3130.      ? "this is a test";
  3131.      close(f);
  3132.  
  3133.  
  3134.      When  opening  a file in the "new" command, the filename can also be a
  3135.      device name, such as "prn:".  The printer can be accessed as shown  in
  3136.      the following example:
  3137.  
  3138.  
  3139.      /*
  3140.              this is a demonstration of dObject's printer handling features
  3141.              open the printer and print 10 lines to it without echoing the
  3142.              lines to the screen
  3143.      */
  3144.      p = new(File,"prn:",1,0,0);
  3145.      writeDevice(p);
  3146.      i = 1;
  3147.      while(i < 10) {
  3148.              ? "printing line ",i;
  3149.              i = i+1;
  3150.      }
  3151.  
  3152.      /*
  3153.              note: on some printers (HP II, Epson EPL-6000) it is necessary
  3154.              to send an ESC E to flush the printer... consult your printer
  3155.              manual to see if the next line is necessary, otherwise the
  3156.              "flush" method should work OK by itself
  3157.      */
  3158.      ? chr(27),'E';
  3159.      flush(p);
  3160.      close(p);
  3161.      ? "printout is done";
  3162.  
  3163.  
  3164.  
  3165.                          12.0 DBASE File Programming
  3166.  
  3167.      12.1 DBASE File Programming
  3168.  
  3169.      dObject  provides  an  extensive  set of built-in methods for handling
  3170.      DBASE data, memo, and index files.    You  can  create  your  own  new
  3171.      DBASE-format  files for storing data, or use existing files already in
  3172.      the DBASE format.  You can also use  and  create  DBASE  index  (.NDX)
  3173.      files.
  3174.  
  3175.  
  3176.  
  3177.  
  3178.  
  3179.                                      - 53 -
  3180.  
  3181.  
  3182. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3183.  
  3184.  
  3185.      12.2 Creating DBASE Files
  3186.  
  3187.      The  following  example  demonstrates  how to create a .DBF file using
  3188.      the String::createDbf() method.  The argument  to  "createDbf"  is  an
  3189.      Collection of  Collections of field defintions.  Each field definition
  3190.      Collection should contain a string that is the  DBASE  field  name,  a
  3191.      character  field  type  ('C'  = char, 'N' = numeric, 'D' = date, 'M' =
  3192.      memo), an Int length, and an Int number of decimals for numerics:
  3193.  
  3194.      /*
  3195.              create a new Dbffile
  3196.      */
  3197.      db = createDbf("test",[
  3198.              ["cfield",'C',32,0],
  3199.              ["nfield",'N',5,0],
  3200.              ["dfield",'D',0,0],
  3201.              ["mfield",'M',512,0]);
  3202.      displayStructure(db);
  3203.  
  3204.  
  3205.      dObject will create a .DBT file for each MEMO field specified  in  the
  3206.      Collection of field definitions.
  3207.  
  3208.  
  3209.      To  set  the  value  of  a  field within the current DBASE file, set a
  3210.      variable with the same name as the field to  a  value,  just  like  in
  3211.      DBASE.   Once  set,  the  field  value  can  be updated in the current
  3212.      record by the "write" method, or a new record can be appended  to  the
  3213.      file using the "write" method:
  3214.  
  3215.  
  3216.      /*
  3217.              store some test data to the database
  3218.      */
  3219.      select(db); % make sure the Dbffile to process is the "current" file
  3220.      i = 1;
  3221.      while(i < 10) {
  3222.              cfield = "test"+asString(i);
  3223.              nfield = i;
  3224.              dfield = date();
  3225.              mfield = "memo" + asString(i);
  3226.              write(db,0L);
  3227.              i = i+1;
  3228.      }
  3229.  
  3230.  
  3231.      The  structure  (field definitions) from a DBF file can be obtained by
  3232.      using the Dbffile::structure() method.  This returns a  Collection  of
  3233.      field definitions  like  the one described above.  The following is an
  3234.      example of how to use the structure method  to  simulate  some  common
  3235.      DBASE commands:
  3236.  
  3237.  
  3238.  
  3239.                                      - 54 -
  3240.  
  3241.  
  3242.                                             Chapter 12: DBASE File Programming
  3243.  
  3244.  
  3245.      /*
  3246.              Dbffile::copyStructure(self,newname)
  3247.              this method copys the structure of self to a new database
  3248.              with name of "newname"
  3249.              only the structure of self is copied; no records are copied
  3250.      */
  3251.      method Dbffile::copyStructure(self,newname)
  3252.      {
  3253.              l = structure(self);
  3254.              createDbf(newname,l);
  3255.      }
  3256.  
  3257.      /*
  3258.              Dbffile::list(self)
  3259.              this method lists the records in a Dbffile to the screen
  3260.      */
  3261.      method Dbffile::list(self)
  3262.      {
  3263.              top(self);
  3264.              fields = structure(self);
  3265.              newline = set("newline");
  3266.              set("newline","");
  3267.              while(!eof(self)) {
  3268.                      for(i=1;i<numFields(self);i=i+1) {
  3269.                              f = at(fields,i);
  3270.                              name = at(f,1);
  3271.                              ? eval(asId(name))," ";
  3272.                      }
  3273.                      ? "\n";
  3274.                      skip(self,1L);
  3275.              }
  3276.              set("newline",newline);
  3277.      }
  3278.  
  3279.  
  3280.              dObject> db2 = copyStructure(db,"test2");
  3281.  
  3282.  
  3283.      12.3 Reading DBASE Files
  3284.  
  3285.      DBF  files can be opened through the use of the "new" message with the
  3286.      name of the DBF file passed as an argument.  Once opened, the  records
  3287.      and  fields within a DBF file are available for reading and for update
  3288.      by your dObject program.   For  example,  to  open  the  "patient.dbf"
  3289.      file, use the statement:
  3290.  
  3291.              dObject> db = new(Dbffile,"patient");
  3292.  
  3293.  
  3294.      The  number  of  records  and  fields  defined  within  a DBF file are
  3295.      available through calls to the "numRecords" and "numFields" methods:
  3296.  
  3297.  
  3298.  
  3299.                                      - 55 -
  3300.  
  3301.  
  3302. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3303.  
  3304.  
  3305.              dObject> ? numFields(db);
  3306.              6
  3307.              dObject> ? numRecords(db);
  3308.              20
  3309.  
  3310.  
  3311.      The current record number is available as a  Long  using  the  "recno"
  3312.      method:
  3313.  
  3314.              dObject> top(db);
  3315.              dObject> ? recno(db),class(recno(db));
  3316.              1 Long
  3317.  
  3318.  
  3319.      Dbffiles   can  be  positioned  by  sending  them  the  "top",  "bot",
  3320.      "locate", and "seek" messages. The  "eof"  method  returns  logical  T
  3321.      when  a  Dbffile is positioned beyond the last record in the file (and
  3322.      otherwise returns logical F).  The following  example  demonstrates  a
  3323.      program that loops over all the records in a DBF file:
  3324.  
  3325.  
  3326.              db = new(Dbffile,"patient");
  3327.              top(db);
  3328.              while(!eof(dbf)) {
  3329.                      ? "at record ",recno(db);
  3330.                      skip(db,1L);
  3331.              }
  3332.  
  3333.  
  3334.      The  "locate"  method  can  be used to locate specific field values of
  3335.      type Int, Real, Char, String, Date, or Logical.   The  first  argument
  3336.      to  the  method  should  be  the  name  of  the  field  to perform the
  3337.      comparison on, and the second the value to  find.    The  search  will
  3338.      always  start  at the current record, so to always search from the top
  3339.      of the database, the "top" method can be used to position the  Dbffile
  3340.      first:
  3341.  
  3342.              dObject> db = new(Dbffile,"patient");
  3343.              dObject> locate(top(db),"lname","lname6");
  3344.  
  3345.  
  3346.      Fields  within  DBF  files  are accessed by using a variable name with
  3347.      the same name as a field in the currently  selected  database,  as  in
  3348.      DBASE:
  3349.  
  3350.              dObject> db = new(Dbffile,"patient");
  3351.              dObject> top(db);
  3352.              dObject> ? lname;
  3353.              lname0
  3354.  
  3355.  
  3356.              dObject> select(db);
  3357.  
  3358.  
  3359.                                      - 56 -
  3360.  
  3361.  
  3362.                                             Chapter 12: DBASE File Programming
  3363.  
  3364.  
  3365.      The  currently  selected  Dbffile  is  available through a call to the
  3366.      Nil::currentDbffile() method:
  3367.  
  3368.              dObject> top(currentDbffile());
  3369.  
  3370.  
  3371.      You can also perform sophisticated calculations over all  the  records
  3372.      in  a  DBASE  file  using  the built-in "sum", "max", "min", and "avg"
  3373.      methods.  These methods accept a  literal  dObject  expression  as  an
  3374.      argument,   and  evaluate  the  sum,  max,  min,  or  average  of  the
  3375.      expression over all  the  records  in  the  file.    For  example,  to
  3376.      calculate  the  minimum and maximum length of a DBASE char field named
  3377.      "lname", your need to evaluate the length of the trimmed  field  value
  3378.      across all  the  records  in the file.  The following commands perform
  3379.      this task:
  3380.  
  3381.              dObject> ? db = new(Dbffile,"patient");
  3382.              dObject> ? min(db,#len(trim(lname)));
  3383.              dObject> ? max(db,#len(trim(lname)));
  3384.  
  3385.  
  3386.      These methods always start from the top of the file.
  3387.  
  3388.  
  3389.      12.4 Using Filters
  3390.  
  3391.      dObject allows you to specify an expression as a "filter" for  a  .DBF
  3392.      file  to  make  it  appear to your application that certain records do
  3393.      not exist.  The expression is evaluated for each record within a  .DBF
  3394.      file,  and unless the expression evaluates to logical true for a given
  3395.      record, the record appears as if it does not  exist.    To  create  an
  3396.      expression   filter   for  a  database,  call  the  Dbffile::setFilter
  3397.      method:
  3398.  
  3399.              dObject> setFilter(db,#(recno(db) > 5L) & (recno(db) < 15L));
  3400.  
  3401.  
  3402.      The above example creates a filter for  a  Dbffile  making  it  appear
  3403.      that  only  the  records  having  record  numbers  between  6  and  14
  3404.      inclusive actually exist in the file.    The  expression  can  be  any
  3405.      valid  dObject  expression,  and  setting a filter in this way affects
  3406.      every future operation done on the database,  including  repositioning
  3407.      with  the  Dbffile::top,  Dbffile::bot, Dbffile::skip, and Dbffile::go
  3408.      methods, as well as editing within the interactive DBASE editor.
  3409.  
  3410.  
  3411.      When  created,   Dbffile   objects   have   an   implied   filter   of
  3412.      logical(true), which  succeeds  for  any  record.  To clear the filter
  3413.      for a Dbffile object, use the Dbffile::clearFilter() method:
  3414.  
  3415.              dObject> clearFilter(db);
  3416.  
  3417.  
  3418.  
  3419.                                      - 57 -
  3420.  
  3421.  
  3422. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3423.  
  3424.  
  3425.      Collections can be created from DBASE fields using the  "asCollection"
  3426.      method.   The argument to this method is an expression to evaluate for
  3427.      each record in the DBASE file.  The Collection returned  contains  one
  3428.      entry for  the value of the expression for each record.  The filtering
  3429.      process descibed above applies to filter  out  unwanted  records.  The
  3430.      following  is  an  example  of  how to create a menu using information
  3431.      from a DBF file using a Collection as the list of  items  to  show  in
  3432.      the menu:
  3433.  
  3434.      /*
  3435.              create a menu of all the last names within a range
  3436.              of records in the dbf file
  3437.      */
  3438.      d = new(Dbffile,"patient");
  3439.      top(d);
  3440.      d = setFilter(d,#(recno(d) >= 8L) & (recno(d) <= 15L));
  3441.      a = sort(asCollection(d,#trim(lname)));
  3442.      m = new(Menu,3,3,5,31,3,a," Last Name ");
  3443.      c = choice(m,1);
  3444.      remove(m);
  3445.      ? "your menu choice was ",c;
  3446.  
  3447.  
  3448.      12.5 Using DBASE Index Files
  3449.  
  3450.      Records  containing field values of interest can be accessed much more
  3451.      quickly using DBASE index files than can be using the "locate"  method
  3452.      described above.    dObject  provides  the  built-in  Ndxfile class to
  3453.      represent DBASE index files.  To  open  an  existing  index  file  and
  3454.      associate  it  with  a  Dbffile variable, use the "useIndex" method of
  3455.      the Dbffile class.  This method returns a new Ndxfile variable:
  3456.  
  3457.              dObject> db = new(Dbffile,"patient");
  3458.              dObject> ndx = useIndex(db,"patient");
  3459.  
  3460.  
  3461.      This method opens the named  index  (with  the  default  extension  of
  3462.      .NDX) and   associates   it  with  the  Dbffile.    This  permits  the
  3463.      Ndxfile::seek method to be used to position the current record in  the
  3464.      Dbffile:
  3465.  
  3466.              dObject> seek(db,"1");
  3467.  
  3468.  
  3469.      To  create  a  new  index  file,  use  the "createIndex" method of the
  3470.      String class.  The "self" argument in this case is  the  name  of  the
  3471.      index  file  to create, followed by a String containing the expression
  3472.      to evaluate for the index, and finally an Int indicator specifying  if
  3473.      the index  is  to be unique (0=not unique, 1=unique).  It also returns
  3474.      a new Ndxfile variable:
  3475.  
  3476.              dObject> ndx = createIndex("test","test",1);
  3477.  
  3478.  
  3479.                                      - 58 -
  3480.  
  3481.  
  3482.                                             Chapter 12: DBASE File Programming
  3483.  
  3484.  
  3485.      The following program demonstrates how to create  an  index  file  and
  3486.      use it to access fields within a Dbffile:
  3487.  
  3488.      /*
  3489.              create an index file for a database
  3490.      */
  3491.      db = new(Dbffile,"patient");
  3492.      index = createIndex(db,"patient","LNAME",0,0);
  3493.      ? "type of index is ",type(index);
  3494.      close(db);
  3495.  
  3496.      /*
  3497.              open the index and print out records in index order
  3498.      */
  3499.      db = new(Dbffile,"patient");
  3500.      useIndex(db,"patient");
  3501.      top(db);
  3502.      while(!eof(db)) {
  3503.              ? recno(db)," ",lname;
  3504.              skip(db,1L);
  3505.      }
  3506.      close(db);
  3507.  
  3508.  
  3509.      12.6 Using Relations
  3510.  
  3511.      dObject  provides  a facility to relate two DBF files throught the use
  3512.      of the Dbffile::setRelation() method.  Calling this method  creates  a
  3513.      relation  between  a  controlling  database (the self parameter) and a
  3514.      related database.      Each   time   the   controlling   database   is
  3515.      re-positioned     (using     the    Dbffile::go(),    Dbffile::seek(),
  3516.      Dbffile::top(), or Dbffile::bot() methods), the  related  database  is
  3517.      re-positioned by  looking  up  an  expression in an index file.  If no
  3518.      index file is specified when the relationship  is  created,  then  the
  3519.      expression  is  evaluated  and interpreted as a record number to go to
  3520.      in the related database.
  3521.  
  3522.  
  3523.      The following example illustrates the use of relations in dObject:
  3524.  
  3525.      /*
  3526.              demonstrate the dObject relation facility between two related
  3527.              DBF files,  first, create a customer file with customer names
  3528.      */
  3529.      custDb = createDbf("customer",[
  3530.              ["cId",'N',8,0],
  3531.              ["cName",'C',32,0],
  3532.              ["cAddress",'C',48,0],
  3533.              ["cCity",'C',16,0],
  3534.              ["cState",'C',2,0],
  3535.              ["cZip",'C',5,0]]);
  3536.  
  3537.  
  3538.  
  3539.                                      - 59 -
  3540.  
  3541.  
  3542. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3543.  
  3544.  
  3545.      /*
  3546.              fill in some test customer names
  3547.      */
  3548.      #define MAXCUST 5
  3549.      for(i=0;i<MAXCUST;i=i+1) {
  3550.              cId = i;
  3551.              cName = "name"+asString(i);
  3552.              cAddress = "";
  3553.              cCity = "Chicago";
  3554.              cState = "IL";
  3555.              cZip = "60640";
  3556.              ? "writing record ",i;
  3557.              write(custDb,0L);
  3558.      }
  3559.      close(custDb);
  3560.  
  3561.      /*
  3562.              create a database of customer purchases
  3563.      */
  3564.      purchaseDb = createDbf("purchase",[
  3565.              ["cId",'N',8,0],
  3566.              ["pItem",'C',32,0],
  3567.              ["pDate",'D',0,0],
  3568.              ["pAmount",'N',8,2]]);
  3569.  
  3570.      /*
  3571.              create some test data
  3572.      */
  3573.      for(i=0;i<MAXCUST;i=i+1)
  3574.              for(j=0;j<2;j=j+1) {
  3575.                      cId = i;
  3576.                      pItem = "item"+asString(i);
  3577.                      pDate = date();
  3578.                      pAmount = 5.25;
  3579.                      write(purchaseDb,0L);
  3580.              }
  3581.      close(purchaseDb);
  3582.  
  3583.      /*
  3584.              find the purchases for customer #3
  3585.      */
  3586.      custDb = new(Dbffile,"customer");
  3587.      purchaseDb = new(Dbffile,"purchase");
  3588.      ndx = createIndex(purchaseDb,"CID","cId",0,0);
  3589.      setRelation(custDb,"cId",select(purchaseDb),select(ndx),0);
  3590.      top(custDb);
  3591.      locate(custDb,"cId",3);
  3592.      ? "record number for customer 3 is ",recno(custDb);
  3593.      ? "customer id field in purchase database is ",recno(purchaseDb);
  3594.  
  3595.  
  3596.  
  3597.  
  3598.  
  3599.                                      - 60 -
  3600.  
  3601.  
  3602.                                             Chapter 12: DBASE File Programming
  3603.  
  3604.  
  3605.      12.7 Editing DBASE Files
  3606.  
  3607.      Using the built-in Window::say() and read() methods  and  the  "Field"
  3608.      class,  the  file DBFLIB.DO provides an example of a DBASE full-screen
  3609.      editor that is invoked by sending the  "edit"  message  to  a  Dbffile
  3610.      object.   You  can  include this editor in your own programs as is, or
  3611.      customize it to fit your own application.  When  invoked,  the  editor
  3612.      will  display  the  field  name  and  value  for each field within the
  3613.      database in the current window, at the current record position.
  3614.  
  3615.  
  3616.      The "edit" method is implemented in the following library  of  Dbffile
  3617.      methods:
  3618.  
  3619.  
  3620.      /*
  3621.              DBFLIB.DO
  3622.              This is a collection of methods for handling DBASE files
  3623.              Includes:
  3624.                      Dbffile::displayStructure(self)
  3625.                      Dbffile::copyStructure(self)
  3626.                      Dbffile::list(self)
  3627.                      Dbffile::edit(self)
  3628.      */
  3629.      #include "keydef.do"
  3630.      #include "colors.do"
  3631.  
  3632.      /*
  3633.              Dbffile::displayStructure(self)
  3634.              this methods prints a description of the structure of a DBASE
  3635.              file similar to that in the DBASE DISPLAY STRUCTURE command
  3636.      */
  3637.      method Dbffile::displayStructure(self)
  3638.      {
  3639.              ? "Structure for\t\t",name(self);
  3640.              ? "Last udpate:\t\t",date(self);
  3641.              ? "Number of records:\t",numRecords(self);
  3642.              fields = structure(self);
  3643.              ? "FIELD\t\t\tTYPE\tLEN\tDEC";
  3644.              for(i=1;i<numFields(self);i=i+1) {
  3645.                      f = at(fields,i);
  3646.                      ? format(at(f,1),"%-24s"),at(f,2),"\t",
  3647.                              at(f,3),"\t",at(f,4);
  3648.              }
  3649.      }
  3650.  
  3651.      /*
  3652.              Dbffile::copyStructure(self,newname)
  3653.              this method copys the structure of self to a new database
  3654.              with name of "newname"
  3655.              only the structure of self is copied; no records are copied
  3656.      */
  3657.  
  3658.  
  3659.                                      - 61 -
  3660.  
  3661.  
  3662. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3663.  
  3664.  
  3665.      method Dbffile::copyStructure(self,newname)
  3666.      {
  3667.              l = structure(self);
  3668.              create(newname,l);
  3669.      }
  3670.  
  3671.      /*
  3672.              Dbffile::list(self)
  3673.              this method lists the records in a Dbffile to the screen
  3674.      */
  3675.      method Dbffile::list(self)
  3676.      {
  3677.              top(self);
  3678.              fields = structure(self);
  3679.              newline = set("newline");
  3680.              set("newline","");
  3681.              while(!eof(self)) {
  3682.                      for(i=1;i<numFields(self);i=i+1) {
  3683.                              f = at(fields,i);
  3684.                              name = at(f,1);
  3685.                              ? eval(asId(name))," ";
  3686.                      }
  3687.                      ? "\n";
  3688.                      skip(self,1L);
  3689.              }
  3690.              set("newline",newline);
  3691.      }
  3692.  
  3693.      /*
  3694.              The following methods implement a DBASE field editor using the
  3695.              dObject Window SAY and READ methods and the FIELD class.
  3696.              first, define a new class called MYFIELD that inherits the behavior of
  3697.              Field, but adds a prompt that is displayed at the bottom of the form
  3698.      */
  3699.      inherit(Field,Myfield,["prompt"]);
  3700.  
  3701.      /*
  3702.              define a method to get the prompt field from a Myfield variable
  3703.      */
  3704.      method Myfield::prompt(self)
  3705.      {
  3706.              return(slot(self,"prompt"));
  3707.      }
  3708.  
  3709.      /*
  3710.              this method will execute whenever the DOWN key is pressed
  3711.              from within a form
  3712.      */
  3713.      method Window::myNextField(self)
  3714.      {
  3715.              n = num(currentField(self));
  3716.              if(n < len(fields)) {
  3717.  
  3718.  
  3719.                                      - 62 -
  3720.  
  3721.  
  3722.                                             Chapter 12: DBASE File Programming
  3723.  
  3724.  
  3725.                      f = at(fields,n+1);
  3726.                      say(promptWindow,0,0,prompt(f),80,112);
  3727.                      gotoField(self,nextField(self));
  3728.              }
  3729.  
  3730.      }
  3731.  
  3732.      /*
  3733.              this method will execute whenever the UP key is pressed
  3734.              from within a form
  3735.      */
  3736.      method Window::myPrevField(self)
  3737.      {
  3738.              n = num(currentField(self));
  3739.              if(n > 1) {
  3740.                      f = at(fields,n-1);
  3741.                      say(promptWindow,0,0,prompt(f),80,112);
  3742.                      gotoField(self,prevField(self));
  3743.              }
  3744.      }
  3745.  
  3746.      /*
  3747.              this method implements a callable text editor for the contents of
  3748.              a field
  3749.      */
  3750.      method Window::myEdit(self)
  3751.      {
  3752.              f = currentField(self);
  3753.              s = eval(asId(name(f)));
  3754.              if(class(s) == "String") {
  3755.                      w = new(Window,1,31,3,name(f),5,5,10,40);
  3756.                      display(s);
  3757.                      remove(w);
  3758.                      gotoField(self,f);
  3759.              }
  3760.      }
  3761.  
  3762.      /*
  3763.              edit a Dbffile using a full screen editor
  3764.      */
  3765.      method Dbffile::edit(self)
  3766.      {
  3767.      /*
  3768.              make a window to run the editor in
  3769.      */
  3770.              w = new(Window,1,FWHITE+LIGHTBLUE,FWHITE+LIGHTBLUE,
  3771.                      name(self),0,0,24,80);
  3772.  
  3773.      /*
  3774.              create the DBASE form based on field definitions within self
  3775.      */
  3776.              clearGets(w);
  3777.  
  3778.  
  3779.                                      - 63 -
  3780.  
  3781.  
  3782. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3783.  
  3784.  
  3785.              sayExp(w,0,1,#name(self),len(name(self)),FWHITE+LIGHTBLUE);
  3786.              sayExp(w,0,20,#"Record=",7,FWHITE+LIGHTBLUE);
  3787.              sayExp(w,0,30,#recno(self),7,FWHITE+LIGHTBLUE);
  3788.  
  3789.              l = structure(self);
  3790.              fields = [];
  3791.  
  3792.      /*
  3793.              for each field in the DBF file, create:
  3794.                      a SAY field with the name of the DBF field
  3795.                      a GET field right next to it to read its value
  3796.      */
  3797.              for(i=1;i<=numFields(self);i=i+1) {
  3798.                      field_def = at(l,i);
  3799.                      fname = at(field_def,1); % name is first element in field def
  3800.                      len = at(field_def,3);
  3801.                      if(len > 40) len = 40;
  3802.                      say(w,i,1,fname,10,31);
  3803.                      fields = append(fields,new(Myfield,w,i,15,fname,len,112,
  3804.                              "Enter the "+asUpper(trim(fname))+ " field"));
  3805.  
  3806.              }
  3807.  
  3808.      /*
  3809.              execute the form
  3810.      */
  3811.              top(self);
  3812.              promptWindow = new(Window,80,112,0,"",24,0,1,80);
  3813.  
  3814.              onKey(w,DOWN,#myNextField(w));
  3815.              onKey(w,UP,#myPrevField(w));
  3816.              onKey(w,F8,#myEdit(w));
  3817.  
  3818.              say(promptWindow,0,0,prompt(at(fields,1)),80,112);
  3819.  
  3820.              read(w);
  3821.              remove(w);
  3822.              remove(promptWindow);
  3823.      }
  3824.  
  3825.  
  3826.  
  3827.      As  another example, the following program displays a directory of DBF
  3828.      files in the current directory and edits the  one  selected  from  the
  3829.      menu:
  3830.  
  3831.  
  3832.      /*
  3833.              this program creates a window, and displays a menu of DBF files
  3834.              available in the current directory.  When the user selects one,
  3835.              the DBF file editor is called to edit the fields and records
  3836.      */
  3837.  
  3838.  
  3839.                                      - 64 -
  3840.  
  3841.  
  3842.                                             Chapter 12: DBASE File Programming
  3843.  
  3844.  
  3845.      w = new(Window,1,7,7," select DBF ",1,1,10,40);
  3846.      s = dir("","*.dbf");
  3847.      while(s != "") {
  3848.              d = new(Dbffile,s);
  3849.              height = numFields(d)+2;
  3850.              edit(d);
  3851.              s = dir("","*.dbf");
  3852.      }
  3853.      remove(w);
  3854.  
  3855.  
  3856.      12.8 Closing DBASE Files
  3857.  
  3858.      To close a Dbffile, use the "close" method:
  3859.  
  3860.  
  3861.              dObject> close(db);
  3862.  
  3863.  
  3864.      To  close  all  the  open  Dbffiles at once, use the Nil::closeAllDbfs
  3865.      method (this will close all open .NDX files also):
  3866.  
  3867.              dObject> closeAllDbfs();
  3868.  
  3869.  
  3870.  
  3871.                           13.0 Graphics Programming
  3872.  
  3873.      13.1 BGI Graphics
  3874.  
  3875.      dObject comes complete with a built-in graphics system  based  on  the
  3876.      Borland Graphics  Interface  (BGI).   The BGI provides over 70 methods
  3877.      for  handling  graphics,  including  methods  to  draw  lines,   arcs,
  3878.      circles, polygons,  and other shapes;  methods for filling shapes in a
  3879.      variety of styles;  and methods for  setting  text  in  a  variety  of
  3880.      fonts.
  3881.  
  3882.  
  3883.      13.2 Graphics Drivers
  3884.  
  3885.      To   begin   with,  you  must  call  the  Int::initGraph()  method  to
  3886.      initialize the graphics  system.    This  will  put  the  screen  into
  3887.      graphics mode  and  allow  further  calls  to the BGI system.  dObject
  3888.      comes with graphics drivers for the following graphics adapters:
  3889.  
  3890.           * CGA
  3891.  
  3892.           * MCGA
  3893.  
  3894.           * EGA
  3895.  
  3896.           * VGA
  3897.  
  3898.  
  3899.                                      - 65 -
  3900.  
  3901.  
  3902. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  3903.  
  3904.  
  3905.           * Hercules
  3906.  
  3907.           * AT&T 400-line
  3908.  
  3909.           * 3270 Graphics Adapter
  3910.  
  3911.           * IBM-8514 Graphics Adapter
  3912.  
  3913.      The self argument to Int::initGraph() is an  integer  flag  specifying
  3914.      the  device  driver  to use ( a value of 0 will detect the best driver
  3915.      to use):
  3916.  
  3917.  
  3918.           * 0 - autodetect
  3919.  
  3920.           * 1 - CGA
  3921.  
  3922.           * 2 - MCGA
  3923.  
  3924.           * 3 - EGA
  3925.  
  3926.           * 4 - EGA64
  3927.  
  3928.           * 5 - EGAMONO
  3929.  
  3930.           * 6 - IBM8514
  3931.  
  3932.           * 7 - Hercules
  3933.  
  3934.           * 8 - AT&T 400
  3935.  
  3936.           * 9 - VGA
  3937.  
  3938.           * 10 - PC 3270
  3939.  
  3940.      You can obtain the name of the current graphics driver through a  call
  3941.      to the Nil::getDriverName() method.
  3942.  
  3943.  
  3944.      dObject  provides  the following methods for initializing and shutting
  3945.      down the BGI graphics system:
  3946.  
  3947.  
  3948.      NAME                 ARGUMENTS            DESCRIPTION
  3949.  
  3950.      Int::initGraph       self, Int, String    initializes the BGI system;
  3951.                                                must be called before any
  3952.                                                other BGI method.  Sets the
  3953.                                                graphics driver to self, the
  3954.                                                graphics mode to the Int
  3955.                                                arg, and the driver path to
  3956.                                                the String arg.
  3957.  
  3958.  
  3959.                                      - 66 -
  3960.  
  3961.  
  3962.                                               Chapter 13: Graphics Programming
  3963.  
  3964.  
  3965.      Nil::detectGraph                          returns a Collection of 2
  3966.                                                Int values specifying the
  3967.                                                current graphics driver and
  3968.                                                mode.
  3969.      Nil::getDriverName                        returns a String containing
  3970.                                                the name of the current
  3971.                                                graphics driver.
  3972.      Int::getModeName     self                 returns a String containing
  3973.                                                the graphics mode name for
  3974.                                                the mode with Int code of
  3975.                                                self.
  3976.      Int::getModeRange    self                 returns a Collection of 2
  3977.                                                Int values specifying the
  3978.                                                min and max mode values for
  3979.                                                the graphics driver with Int
  3980.                                                code of self.
  3981.      Int::setGraphMode    self                 changes the graphics mode to
  3982.                                                self.
  3983.      Nil::getGraphMode                         returns an Int containing
  3984.                                                the current graphics mode.
  3985.      Nil::getMaxMode                           returns an Int containing
  3986.                                                the maximum mode number for
  3987.                                                the currently loaded driver.
  3988.      Nil::graphDefaults                        sets the graphics system to
  3989.                                                default values (see next
  3990.                                                section).
  3991.      Nil::closeGraph                           closes the graphics system,
  3992.                                                unloads the driver from
  3993.                                                memory, and restores the CRT
  3994.                                                to its original state before
  3995.                                                initGraph() was called.
  3996.      Nil::restoreCrtMode                       restores the CRT to its
  3997.                                                original state.
  3998.  
  3999.      13.3 Default Graphics Settings
  4000.  
  4001.      You can set the graphics system to  its  default  settings  through  a
  4002.      call to  the Nil::graphDefaults() method.  These defaults settings are
  4003.      as follows:
  4004.  
  4005.  
  4006.           * Viewport:  mamimum device resolution
  4007.  
  4008.           * Clipping:  on
  4009.  
  4010.           * Palette:  default for drive
  4011.  
  4012.           * Background color:  0
  4013.  
  4014.           * Drawing color:  max color
  4015.  
  4016.           * Fill style:  solid fill
  4017.  
  4018.  
  4019.                                      - 67 -
  4020.  
  4021.  
  4022. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  4023.  
  4024.  
  4025.           * Fill color:  max color
  4026.  
  4027.           * Line style:  solid line
  4028.  
  4029.           * Hardware font direction:  horizontal
  4030.  
  4031.           * Font size:  1
  4032.  
  4033.           * Font justification:  left top
  4034.  
  4035.           * Current position:  home (0,0)
  4036.  
  4037.      13.4 Current Graphics Position
  4038.  
  4039.      The BGI system maintains the current X,Y graphics co-ordinate that  is
  4040.      referred to  as  the  current position (CP).  The current position can
  4041.      be obtained through calls to the Nil::getx() and Nil::gety()  methods,
  4042.      each of  which  return  an  Int  value.    The CP can be set using the
  4043.      Int::moveto() and Int::moveRel() methods, with the self arg  equal  to
  4044.      the  X  value  to  move  to,  and  the  first  argument being an Int Y
  4045.      co-ordinate.  Int::moveTo() uses  and  absolute  co-ordinate,  whereas
  4046.      Int::moveRel() moves relative to the current position:
  4047.  
  4048.  
  4049.  
  4050.              /*
  4051.                      move the graphics CP
  4052.              */
  4053.              moveto(100,100); % now at 100,100
  4054.              moveRel(100,100); % now at 200,200
  4055.  
  4056.  
  4057.  
  4058.      dObject  provides  the  following methods for maintinaing the graphics
  4059.      CP:
  4060.  
  4061.  
  4062.      NAME                 ARGUMENTS            DESCRIPTION
  4063.  
  4064.      Nil::getX                                 returns the x co-ordinate of
  4065.                                                the CP
  4066.      Nil::getY                                 returns the y co-ordinate of
  4067.                                                the CP
  4068.      Int::moveTo          self, Int            moves the CP to X,Y of self,
  4069.                                                Int arg
  4070.      Int::moveRel         self, Int            moves the CP the X,Y
  4071.                                                relative distance  of self,
  4072.                                                Int arg
  4073.      Nil::getMaxX                              returns the max X value for
  4074.                                                the current graphics driver
  4075.                                                and mode
  4076.      Nil::getMaxY                              returns the max Y value for
  4077.  
  4078.  
  4079.                                      - 68 -
  4080.  
  4081.  
  4082.                                               Chapter 13: Graphics Programming
  4083.  
  4084.  
  4085.                                                the current graphics driver
  4086.                                                and mode
  4087.  
  4088.      13.5 Drawing Lines
  4089.  
  4090.      Lines are drawn using the  Int::line()  method,  passing  it  the  X,Y
  4091.      positions of  the  beginning  and  end  points.  The following example
  4092.      draws a line from the point 5,5 to the point 100,100:
  4093.  
  4094.              dObject> line(5,5,100,100);
  4095.  
  4096.  
  4097.      The following methods are provided for drawing lines:
  4098.  
  4099.  
  4100.      NAME                 ARGUMENTS            DESCRIPTION
  4101.  
  4102.      Int::setLineStyle    self, Int, Int       sets the current line style
  4103.                                                to the code in self; sets
  4104.                                                the current pattern to the
  4105.                                                first Int arg code, and the
  4106.                                                current thickness to the
  4107.                                                second Int arg.  Line style
  4108.                                                codes are 0=solid, 1=dotted,
  4109.                                                2=center, 3=dashes,
  4110.                                                4=user-defined.  You can
  4111.                                                define a line style by using
  4112.                                                a 16-bit pattern in the
  4113.                                                first Int arg, where whenver
  4114.                                                a bit in the pattern is set
  4115.                                                to one, the corresponding
  4116.                                                pixel in the line is drawn
  4117.                                                in the current drawing
  4118.                                                color.  For example, a solid
  4119.                                                line is  represented by the
  4120.                                                value $FFFF (all one's), and
  4121.                                                a dashed line is $3333 or
  4122.                                                $0F0F.  Thickness codes in
  4123.                                                the second Int arg are 0=1
  4124.                                                pixel wide, 3=3 pixels wide.
  4125.      Nil::getLineSettings                      returns collection of 3 Int
  4126.                                                args representing current
  4127.                                                line style, user-defined
  4128.                                                pattern, and thickness code
  4129.                                                as described above.
  4130.      Int::line            self, Int, Int, Int  draws a line in the current
  4131.                                                drawing color. Arguments are
  4132.                                                X,Y of start point and X,Y
  4133.                                                of end point.
  4134.      Int::linerel         self, Int            draws a line in the current
  4135.                                                drawing color from current
  4136.                                                position to relative offset
  4137.  
  4138.  
  4139.                                      - 69 -
  4140.  
  4141.  
  4142. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  4143.  
  4144.  
  4145.                                                of self, Int arg.
  4146.      Int::lineto          self, Int            draws a line in the current
  4147.                                                drawing color from current
  4148.                                                position to X,Y position of
  4149.                                                self, Int arg.
  4150.      Int::setWriteMode    self                 sets the writing mode for
  4151.                                                line drawing to self; if
  4152.                                                self = 0 the line will
  4153.                                                overwrite what is on the
  4154.                                                screen; if self=1 the line
  4155.                                                pixels will be XOR'd with
  4156.                                                the pixels on the screen.
  4157.  
  4158.      13.6 Drawing Circles
  4159.  
  4160.      The following methods are provided for drawing circles and arcs:
  4161.  
  4162.  
  4163.      NAME                 ARGUMENTS            DESCRIPTION
  4164.  
  4165.      Int::arc             self, Int, Int, Int, draws a circular arc in the
  4166.                           Int                  current  drawing color.
  4167.                                                Arguments are X,Y center,
  4168.                                                start angle, end angle, and
  4169.                                                radius.
  4170.      Int::circle          self, Int, Int       draws a circle in the
  4171.                                                current drawing color.
  4172.                                                Arguments are X,Y of center,
  4173.                                                and radius.
  4174.      Nil::getArcCoords                         returns a Collection of 6
  4175.                                                Int values containing the
  4176.                                                x,y center point, x,y start
  4177.                                                pos, and x,y end pos of the
  4178.                                                arc.  This is useful if you
  4179.                                                need to make a line meet at
  4180.                                                the end of an arc.
  4181.  
  4182.      13.7 Drawing Ellipses and Pie Charts
  4183.  
  4184.      The following methods  are  provided  for  drawing  ellipses  and  pie
  4185.      charts:
  4186.  
  4187.  
  4188.      NAME                 ARGUMENTS            DESCRIPTION
  4189.  
  4190.      Int::ellipse         self, Int, Int, Int, draws an ellipse in the
  4191.                           Int, Int             current drawing color.  Args
  4192.                                                are center point X,Y, start
  4193.                                                angle, end angle, and X and
  4194.                                                Y radius.
  4195.      Int::fillEllipse     self, Int, Int, Int  draws an ellipse and fills
  4196.                                                it with the current fill
  4197.  
  4198.  
  4199.                                      - 70 -
  4200.  
  4201.  
  4202.                                               Chapter 13: Graphics Programming
  4203.  
  4204.  
  4205.                                                pattern in the current fill
  4206.                                                color.  Args are X, Y, X
  4207.                                                radius, and Y radius.
  4208.      Int::pieSlice        self, Int, Int, Int, draws and fills a pie slice
  4209.                           Int                  using current fill pattern
  4210.                                                and drawing color.
  4211.                                                Arguments are X,Y center,
  4212.                                                start angle, end angle, and
  4213.                                                radius.
  4214.      Int::pieSliceXY      self, Int, Int, Int, draws and fills an
  4215.                           Int, Int             elliptical pie slice using
  4216.                                                current fill pattern and
  4217.                                                drawing color.   Arguments
  4218.                                                are X,Y center, start angle,
  4219.                                                end angle, X radius, and Y
  4220.                                                radius.
  4221.      Nil::getAspectRatio                       returns Collection of 2 Int
  4222.                                                value representing the x and
  4223.                                                y aspect ratio correction
  4224.                                                values of the current
  4225.                                                graphics mode.
  4226.      setAspectRatio       self, Int            sets the x and y
  4227.                                                aspect-ratio correction
  4228.                                                factors  to self and Int arg
  4229.                                                respectively.
  4230.  
  4231.      13.8 Drawing Rectangles and Bars
  4232.  
  4233.      dObject  provides  the  following  methods for drawing rectangles, bar
  4234.      graphs, and polygons:
  4235.  
  4236.  
  4237.      NAME                 ARGUMENTS            DESCRIPTION
  4238.  
  4239.      Int::rectangle       self, Int, Int, Int  draws a rectangle in the
  4240.                                                current line style,
  4241.                                                thickness, and drawing
  4242.                                                color.  Arguments are left,
  4243.                                                top, right, and bottom
  4244.                                                co-ordinates of the
  4245.                                                rectangle to draw  (from
  4246.                                                (left,top) to
  4247.                                                (right,bottom)).
  4248.      Int::bar             self, Int, Int, Int  draws a rectangular bar in
  4249.                                                the current line style,
  4250.                                                thickness, and drawing
  4251.                                                color, and fills it using
  4252.                                                the current fill pattern and
  4253.                                                fill color.  Arguments are
  4254.                                                left, top, right, and bottom
  4255.                                                co-ordinates of the
  4256.                                                rectangle to draw (from
  4257.  
  4258.  
  4259.                                      - 71 -
  4260.  
  4261.  
  4262. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  4263.  
  4264.  
  4265.                                                (left,top) to
  4266.                                                (right,bottom)).
  4267.      Int::bar3d           self, Int, Int, Int, draws a rectangular 3-D bar
  4268.                           Int, Int             in  the current line style,
  4269.                                                thickness, and drawing
  4270.                                                color, and fills it using
  4271.                                                the current fill pattern and
  4272.                                                fill color.  Arguments are
  4273.                                                left, top, right, and bottom
  4274.                                                co-ordinates of the
  4275.                                                rectangle to draw (from
  4276.                                                (left,top)  to
  4277.                                                (right,bottom)), the depth
  4278.                                                of the bar, and a flag
  4279.                                                indicating if a top to the
  4280.                                                bar should be drawn (0=no,
  4281.                                                1=yes).
  4282.  
  4283.      13.9 Drawing Polygons
  4284.  
  4285.      dObject provides the following methods for drawing polygons:
  4286.  
  4287.  
  4288.      NAME                 ARGUMENTS            DESCRIPTION
  4289.  
  4290.      Collection::drawPoly self                 draws a polygon with as many
  4291.                                                points as Int value pairs in
  4292.                                                the collection; each Int
  4293.                                                pair is an x,y co-ordinate
  4294.                                                of a vertex on the polygon.
  4295.      Collection::fillPoly self                 draws a polygon with as many
  4296.                                                points as Int value pairs in
  4297.                                                the collection and fills it
  4298.                                                using the current fill style
  4299.                                                and fill color; each Int
  4300.                                                pair is an x,y co-ordinate
  4301.                                                of a vertex on the polygon.
  4302.  
  4303.      13.10 Palettes
  4304.  
  4305.      The BGI graphics screen consists of an array of pixels  controlled  by
  4306.      a color   table  called  a  palette.    The  background  color  always
  4307.      corresponds to pixel value 0.  The  drawing  color  is  the  value  to
  4308.      which pixels  are  set  when lines or shapes are being drawn.  You can
  4309.      select a drawing color with the Int::setColor() method.
  4310.  
  4311.  
  4312.      NAME                 ARGUMENTS            DESCRIPTION
  4313.  
  4314.      Int::setBkColor      self                 sets the current background
  4315.                                                color to self
  4316.      Nil::getBkcolor      self                 returns the current
  4317.  
  4318.  
  4319.                                      - 72 -
  4320.  
  4321.  
  4322.                                               Chapter 13: Graphics Programming
  4323.  
  4324.  
  4325.                                                background color
  4326.      Int::setColor        self                 sets the current drawing
  4327.                                                color to self
  4328.      Nil::getColor                             returns the current drawing
  4329.                                                color
  4330.      Nil::getMaxColor                          returns the maximum color
  4331.                                                value available in the
  4332.                                                current graphics mode
  4333.      Int::setPalette      self, Int            changes the color value
  4334.                                                stored under self to the
  4335.                                                color in the Int arg
  4336.      Collection::setAllPaletteself                 sets list of new palette
  4337.                                                colors. self  must be a
  4338.                                                Collection of 8 Int values
  4339.                                                specifying the colors.
  4340.  
  4341.      13.11 Filling Shapes
  4342.  
  4343.      You can fill the shapes drawn  with  the  circle,  ellipse,  bar,  and
  4344.      polygon  shape  drawing  methods  with the Int::floodFill() method, or
  4345.      combine drawing and filling into one  step  with  the  fillPoly()  and
  4346.      pieSlice() methods.    You  can  select a predefined fill pattern with
  4347.      setFillStyle,   and   define    your    own    fill    pattern    with
  4348.      setFillPattern().
  4349.  
  4350.  
  4351.      The  predefined  fill  pattern codes recognized by Int::setFillStyle()
  4352.      are as follows (as defined in the included file BGIDEF.DO):
  4353.  
  4354.           * 0 (EMPTY_FILL) - fill with background color
  4355.  
  4356.           * 1 (SOLID_FILL) - solid fill
  4357.  
  4358.           * 2 (LINE_FILL) - fill with ----
  4359.  
  4360.           * 3 (LTSLASH_FILL) - fill with ///
  4361.  
  4362.           * 4 (SLASH_FILL) - fill with ///, thick lines
  4363.  
  4364.           * 5 (BKSLASH_FILL) - fill with backslash, thick lines
  4365.  
  4366.           * 6 (LTBACKSLASH_FILL) - fill with backslash
  4367.  
  4368.           * 7 (HATCH_FILL) - light hatch fill
  4369.  
  4370.           * 8 (XHATCH_FILL) - heavy cross hatch fill
  4371.  
  4372.           * 9 (INTERLEAVE_FILL) - interleaving line fill
  4373.  
  4374.           * 10 (WIDE_DOT_FILL) - widely spaced dot fill
  4375.  
  4376.           * 11 (CLOSE_DOT_FILL) - closely spaced dot fill
  4377.  
  4378.  
  4379.                                      - 73 -
  4380.  
  4381.  
  4382. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  4383.  
  4384.  
  4385.           *  12  (USER_FILL)  -   user-defined   fill   pattern   (see
  4386.           Collection::setFillPattern())
  4387.  
  4388.      The following methods are provided for filling shapes:
  4389.  
  4390.  
  4391.      NAME                 ARGUMENTS            DESCRIPTION
  4392.  
  4393.      Nil::getFillSettings                      returns a Collection of 2
  4394.                                                Int values; the first is the
  4395.                                                current fill pattern; the
  4396.                                                second is the current fill
  4397.                                                color
  4398.      Int::setFillStyle    self, Int            sets the current fill
  4399.                                                pattern to the predefined
  4400.                                                pattern with a code of self
  4401.                                                and the current fill color
  4402.                                                to the Int arg
  4403.      Collection::setFillPatternself, Int            sets the current fill
  4404.                                                pattern to a user-defined
  4405.                                                Collection of 8 Int color
  4406.                                                values. Each Int value
  4407.                                                represents a byte of 8
  4408.                                                pixels; whenever a bit in
  4409.                                                the pixel pattern is set to
  4410.                                                1, the corresponding pixel
  4411.                                                will be plotted.  The Int
  4412.                                                arg is the fill color to
  4413.                                                use.
  4414.      Nil::getFillPattern                       returns the current
  4415.                                                user-defined fill pattern as
  4416.                                                a Collection of 8 Int
  4417.                                                values.
  4418.      Int::floodFill       self, Int, Int       fills an enclosed area on
  4419.                                                the graphics screen.  Self
  4420.                                                and the first Int arg form a
  4421.                                                "seek point": within the
  4422.                                                enclosed area to be filled.
  4423.                                                The are bounded by the color
  4424.                                                indicated in the second Int
  4425.                                                arg is flooded with the
  4426.                                                current fill pattern and
  4427.                                                fill color.  If the seed
  4428.                                                point is within an enclosed
  4429.                                                area, the the inside will be
  4430.                                                filled.  If the seed is
  4431.                                                outside the enclosed the
  4432.                                                area, then the exterior will
  4433.                                                be filled.
  4434.  
  4435.  
  4436.  
  4437.  
  4438.  
  4439.                                      - 74 -
  4440.  
  4441.  
  4442.                                               Chapter 13: Graphics Programming
  4443.  
  4444.  
  4445.      13.12 Fonts and Text in Graphics Mode
  4446.  
  4447.      You  can  also  output  text  in a variety of fonts, sizes, and styles
  4448.      from within dObject's BGI graphics mode.  Text output is  accomplished
  4449.      by  calling  the  String::outText()  or  Int:outTextXY() methods after
  4450.      defining a current character font.
  4451.  
  4452.  
  4453.      Text justification constants in horizontal mode:
  4454.  
  4455.           * 0 - left horizontal
  4456.  
  4457.           * 1 - center horizontal
  4458.  
  4459.           * 2 - right horizontal
  4460.  
  4461.      Text justification constants in vertical mode:
  4462.  
  4463.           * 0 - bottom vertical
  4464.  
  4465.           * 2 - top vertical
  4466.  
  4467.      dObject provides  the  following  methods  for  manipulating  text  in
  4468.      graphics mode:
  4469.  
  4470.  
  4471.      NAME                 ARGUMENTS            DESCRIPTION
  4472.  
  4473.      String::outText      self                 outputs a string to the
  4474.                                                current graphics position
  4475.                                                (CP).
  4476.      Int::outTextXY       self, Int, String    outputs String arg to x,y
  4477.                                                location of self, Int arg
  4478.      String::textHeight   self                 returns height of self in
  4479.                                                pixels as Int
  4480.      String::textWidth    self                 returns width of self in
  4481.                                                pixels as Int
  4482.      Nil::getTextSettings                      returns Collection of 4 Int
  4483.                                                values indicating current
  4484.                                                text font, direction, size,
  4485.                                                and justification
  4486.      Int::setTextJustify  self, Int            sets justification to
  4487.                                                horizontal code of self and
  4488.                                                vertical code of Int arg.
  4489.                                                 Horizontal values:
  4490.                                                0=left,1=center,2=right
  4491.                                                Vertical values:
  4492.                                                0=bottom,1=top
  4493.      Int::setTextStyle    self, Int, Int       sets current text font to
  4494.                                                self; sets current direction
  4495.                                                to first Int arg, and
  4496.                                                current char size to second
  4497.  
  4498.  
  4499.                                      - 75 -
  4500.  
  4501.  
  4502. dObject Version 1.0 (c) 1991 Intelligent Systems Research
  4503.  
  4504.  
  4505.                                                Int arg.  Text direction
  4506.                                                codes are 0=horizontal (left
  4507.                                                to right), 1=vertical
  4508.                                                (bottom to top).
  4509.      Int::setUserCharSize self, Int, Int, Int  sets width and height ratio
  4510.                                                for stroked fonts.  Sets
  4511.                                                scale factors for x width, x
  4512.                                                height, y width, and y
  4513.                                                height to self and the 3 Int
  4514.                                                args respectively.
  4515.  
  4516.      13.13 Viewports
  4517.  
  4518.      Your  system  contains  between one and four screen-page buffers where
  4519.      screen  images  are  stored  dot-by-dot,  depending  on  the  graphics
  4520.      hardware installed.    You  can  specify  which  screen page is active
  4521.      (where graphics methods place their output) and which page is  visible
  4522.      using  the  Int::setActivePage() and Int::setVisualPage() methods. You
  4523.      can specify a region of the display screen where  clipping  is  active
  4524.      through a call to the setViewPort() method.
  4525.  
  4526.  
  4527.      dObject provides the following viewport-related methods:
  4528.  
  4529.  
  4530.      NAME                 ARGUMENTS            DESCRIPTION
  4531.  
  4532.      Int::setViewPort     self, Int, Int, Int, sets the current viewport to
  4533.                           Int                  the absolute screen
  4534.                                                co-ordinates left, top,
  4535.                                                right, bottom corresponding
  4536.                                                to the self argument and the
  4537.                                                first three Int arguments
  4538.                                                respectively. The final Int
  4539.                                                arg is a flag indicating if
  4540.                                                clipping is on or off (0 =
  4541.                                                off, 1 = on).
  4542.      Nil::getViewSettings                      returns a Collection of 5
  4543.                                                Int value specifying the
  4544.                                                left, top right, and bottom
  4545.                                                screen co-ordinates of the
  4546.                                                current viewport, and an Int
  4547.                                                flag indicating if clipping
  4548.                                                is on or off.
  4549.      Int::setActivePage   self                 sets the active graphics
  4550.                                                page to page  number of
  4551.                                                self.
  4552.      Int::setVisualPage   self                 sets the visible graphics
  4553.                                                page to page number of self.
  4554.      Nil::clearViewPort   self                 clears the current viewport
  4555.                                                and moves the CP to (0,0).
  4556.      Nil::clearDevice     self                 clears the entire screen and
  4557.  
  4558.  
  4559.                                      - 76 -
  4560.  
  4561.  
  4562.                                               Chapter 13: Graphics Programming
  4563.  
  4564.  
  4565.                                                moves the CP to (0,0).
  4566.  
  4567.      13.14 Pixels and Images
  4568.  
  4569.      The  BGI  system also provides several methods for manipulating images
  4570.      and pixels on the graphics screen:
  4571.  
  4572.  
  4573.      NAME                 ARGUMENTS            DESCRIPTION
  4574.  
  4575.      Int::getPixel        self, Int            returns the pixel color at
  4576.                                                location x,y specified by
  4577.                                                self and Int arg
  4578.      Int::putPixel        self, Int, Int       sets the pixel at location
  4579.                                                x,y (self, Int arg) to color
  4580.                                                specified by second Int arg
  4581.      Int::getImage        self, Int            returns image stored at x,y
  4582.                                                of self, Int arg
  4583.      Int::imageSize       self, Int, Int, Int  returns an Int number of
  4584.                                                bytes necessary to store a
  4585.                                                rectangular area of the
  4586.                                                screen.  Args are left, top,
  4587.                                                right, and bottom
  4588.                                                co-ordinates of the region.
  4589.      Int::putImage        self, Int, Image, Intwrites an image to the
  4590.                                                screen at x,y of self, first
  4591.                                                Int arg.  Second Int arg
  4592.                                                specifies how bits of the
  4593.                                                image will be combined with
  4594.                                                bits already on the screen:
  4595.                                                copy = 0, xor = 1, or = 2,
  4596.                                                and = 3, not = 4.
  4597.  
  4598.  
  4599.  
  4600.  
  4601.  
  4602.  
  4603.  
  4604.  
  4605.  
  4606.  
  4607.  
  4608.  
  4609.  
  4610.  
  4611.  
  4612.  
  4613.  
  4614.  
  4615.  
  4616.  
  4617.  
  4618.  
  4619.                                      - 77 -
  4620.  
  4621.